From: Sascha Wildner Date: Tue, 17 Oct 2017 07:36:30 +0000 (+0200) Subject: Remove "kernel ppp", i.e. if_ppp.ko and pppd(8). X-Git-Tag: v5.3.0~1013 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/d9d67b5976be7caf272382a562fdbf8906f7811b Remove "kernel ppp", i.e. if_ppp.ko and pppd(8). It has been replaced by ppp(8), in conjunction with tun(4). While here, rename the ppp-user rc script to 'ppp' and fix up REQUIRE/PROVIDE situation. --- diff --git a/Makefile_upgrade.inc b/Makefile_upgrade.inc index c2318eae06..cfd7dab41a 100644 --- a/Makefile_upgrade.inc +++ b/Makefile_upgrade.inc @@ -3250,6 +3250,17 @@ TO_REMOVE+=/usr/share/man/man3/mparse_reset.3.gz TO_REMOVE+=/usr/share/man/man3/mparse_result.3.gz TO_REMOVE+=/usr/share/man/man3/mparse_strerror.3.gz TO_REMOVE+=/usr/share/man/man3/mparse_strlevel.3.gz +TO_REMOVE+=/boot/kernel/if_ppp.ko +TO_REMOVE+=/etc/rc.d/ppp-user +TO_REMOVE+=/usr/include/net/ppp +TO_REMOVE+=/usr/include/ppp_layer/ppp_comp.h +TO_REMOVE+=/usr/sbin/pppd +TO_REMOVE+=/usr/sbin/pppstats +TO_REMOVE+=/usr/share/examples/pppd +TO_REMOVE+=/usr/share/man/man4/if_ppp.4.gz +TO_REMOVE+=/usr/share/man/man4/ppp.4.gz +TO_REMOVE+=/usr/share/man/man8/pppd.8.gz +TO_REMOVE+=/usr/share/man/man8/pppstats.8.gz .if !defined(WANT_INSTALLER) TO_REMOVE+=/usr/sbin/dfuibe_installer diff --git a/UPDATING b/UPDATING index 4b7e31f8e9..3e9848f1ab 100644 --- a/UPDATING +++ b/UPDATING @@ -8,6 +8,18 @@ # If you discover any problem, please contact the bugs@lists.dragonflybsd.org # mailing list with the details. ++-----------------------------------------------------------------------+ ++ UPGRADING DRAGONFLY FROM 5.0 TO LATER VERSIONS + ++-----------------------------------------------------------------------+ + +IF_PPP AND PPPD REMOVED +----------------------- + +It has been replaced by "user ppp", i.e. ppp(8) and tun(4). It had +already been removed from our default kernel configuration before 5.0, +so only people with custom configurations based on earlier X86_64_GENERIC +will have to remove it manually. + +-----------------------------------------------------------------------+ + UPGRADING DRAGONFLY FROM 4.8 TO LATER VERSIONS + +-----------------------------------------------------------------------+ diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist index 7dbc821080..50a4dc6ec2 100644 --- a/etc/mtree/BSD.include.dist +++ b/etc/mtree/BSD.include.dist @@ -244,8 +244,6 @@ .. pf .. - ppp - .. ppp_layer .. sl diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist index 1890d1c7fd..b039f9de38 100644 --- a/etc/mtree/BSD.usr.dist +++ b/etc/mtree/BSD.usr.dist @@ -215,8 +215,6 @@ .. ppp .. - pppd - .. printing .. puffs diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index 2d26f4c934..0b436b2319 100644 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -17,7 +17,7 @@ FILES= DAEMON LOGIN NETWORKING SERVERS \ mountd moused mroute6d mrouted msgs \ named netif netoptions newsyslog \ network_ipv6 nfsclient nfsd nfsserver nisdomain nscd nsswitch \ - dntpd othermta pf pflog powerd ppp ppp-user pppoed pwcheck \ + dntpd othermta pf pflog powerd ppp pppoed pwcheck \ quota random rarpd rcconf resident rndcontrol root route6d routed \ routing rpcbind rtadvd rtsold rwho sysdb savecore sdpd securelevel \ sendmail sensorsd serial sppp sshd statd swap1 syscons sysctl syslogd sysvipcd \ diff --git a/etc/rc.d/NETWORKING b/etc/rc.d/NETWORKING index d04772bfc7..f96de4fe4f 100644 --- a/etc/rc.d/NETWORKING +++ b/etc/rc.d/NETWORKING @@ -5,7 +5,7 @@ # # PROVIDE: NETWORKING NETWORK -# REQUIRE: netif routing network_ipv6 ppp-user +# REQUIRE: netif routing network_ipv6 ppp # REQUIRE: routed mrouted route6d mroute6d # This is a dummy dependency, for services which require networking diff --git a/etc/rc.d/ipfw b/etc/rc.d/ipfw index 5107d14bbf..30c0ef8efe 100644 --- a/etc/rc.d/ipfw +++ b/etc/rc.d/ipfw @@ -4,7 +4,7 @@ # # PROVIDE: ipfw -# REQUIRE: ppp-user +# REQUIRE: ppp # BEFORE: NETWORKING . /etc/rc.subr diff --git a/etc/rc.d/ppp b/etc/rc.d/ppp index 3e7ea0d5de..ae50e73743 100644 --- a/etc/rc.d/ppp +++ b/etc/rc.d/ppp @@ -1,67 +1,67 @@ #!/bin/sh # -# $NetBSD: ppp,v 1.6 2002/03/22 04:33:59 thorpej Exp $ -# $FreeBSD: src/etc/rc.d/ppp,v 1.2 2002/06/13 22:14:36 gordon Exp $ -# $DragonFly: src/etc/rc.d/ppp,v 1.3 2005/11/19 21:47:32 swildner Exp $ +# $FreeBSD: src/etc/rc.d/ppp-user,v 1.4 2003/04/18 17:55:05 mtm Exp $ # # PROVIDE: ppp -# REQUIRE: mountcritremote syslogd -# BEFORE: SERVERS -# -# Note that this means that syslogd will not be listening on -# any PPP addresses. This is considered a feature. -# +# REQUIRE: netif . /etc/rc.subr name="ppp" +rcvar="ppp_enable" start_cmd="ppp_start" stop_cmd="ppp_stop" -sig_stop="-INT" -sig_hup="-HUP" -hup_cmd="ppp_hup" -extra_commands="hup" ppp_start() { - # /etc/ppp/peers and $ppp_peers contain boot configuration - # information for pppd. each value in $ppp_peers that has a - # file in /etc/ppp/peers of the same name, will be run as - # `pppd call '. + local _punct_c _punct _ppp_unit + _profile=${ppp_profile} + + _punct=". - / +" + for _punct_c in $_punct; do + _profile=`ltr ${_profile} ${_punct_c} '_'` + done + + # Establish ppp mode. # - if [ -n "$ppp_peers" ]; then - set -- $ppp_peers - echo -n "Starting pppd:" - while [ $# -ge 1 ]; do - peer=$1 - shift - if [ -f /etc/ppp/peers/$peer ]; then - pppd call $peer - echo -n " $peer" - fi - done - echo "." + if [ "${ppp_mode}" != "ddial" -a "${ppp_mode}" != "direct" \ + -a "${ppp_mode}" != "dedicated" \ + -a "${ppp_mode}" != "background" ]; then + ppp_mode="auto" fi -} -ppp_hup() -{ - pids="`check_process pppd`" - if [ -n "$pids" ]; then - for pid in $pids; do - kill $sig_hup $pid - done + ppp_command="/usr/sbin/ppp -quiet -${ppp_mode}" + + # Switch on NAT mode? + # + case ${ppp_nat} in + [Yy][Ee][Ss]) + ppp_command="${ppp_command} -nat" + ;; + esac + + # Check whether we are asked to use a specific unit + # + eval _ppp_unit=\$ppp_${_profile}_unit + if [ -n "${_ppp_unit}" ]; then + ppp_command="${ppp_command} -unit${_ppp_unit}" fi + + ppp_command="${ppp_command} ${ppp_profile}" + + echo "Starting ppp as \"${ppp_user}\"" + su -m ${ppp_user} -c "exec ${ppp_command}" } ppp_stop() { - pids="`check_process pppd`" - if [ -n "$pids" ]; then - for pid in $pids; do - kill $sig_stop $pid + pids=`check_process /usr/sbin/ppp` + if [ -n "${pids}" ]; then + for pid in ${pids}; do + kill -TERM ${pid} done + wait_for_pids ${pids} fi } diff --git a/etc/rc.d/ppp-user b/etc/rc.d/ppp-user deleted file mode 100644 index b8eab95000..0000000000 --- a/etc/rc.d/ppp-user +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/sh -# -# $FreeBSD: src/etc/rc.d/ppp-user,v 1.4 2003/04/18 17:55:05 mtm Exp $ -# - -# PROVIDE: ppp-user -# REQUIRE: netif - -. /etc/rc.subr - -name="ppp" -rcvar="ppp_enable" -start_cmd="ppp_start" -stop_cmd="ppp_stop" - -ppp_start() -{ - local _punct_c _punct _ppp_unit - _profile=${ppp_profile} - - _punct=". - / +" - for _punct_c in $_punct; do - _profile=`ltr ${_profile} ${_punct_c} '_'` - done - - # Establish ppp mode. - # - if [ "${ppp_mode}" != "ddial" -a "${ppp_mode}" != "direct" \ - -a "${ppp_mode}" != "dedicated" \ - -a "${ppp_mode}" != "background" ]; then - ppp_mode="auto" - fi - - ppp_command="/usr/sbin/ppp -quiet -${ppp_mode}" - - # Switch on NAT mode? - # - case ${ppp_nat} in - [Yy][Ee][Ss]) - ppp_command="${ppp_command} -nat" - ;; - esac - - # Check whether we are asked to use a specific unit - # - eval _ppp_unit=\$ppp_${_profile}_unit - if [ -n "${_ppp_unit}" ]; then - ppp_command="${ppp_command} -unit${_ppp_unit}" - fi - - ppp_command="${ppp_command} ${ppp_profile}" - - echo "Starting ppp as \"${ppp_user}\"" - su -m ${ppp_user} -c "exec ${ppp_command}" -} - -ppp_stop() -{ - pids=`check_process /usr/sbin/ppp` - if [ -n "${pids}" ]; then - for pid in ${pids}; do - kill -TERM ${pid} - done - wait_for_pids ${pids} - fi -} - -load_rc_config $name -run_rc_command "$1" diff --git a/etc/rc.d/routing b/etc/rc.d/routing index 82b4d9dcae..226e6c13a7 100644 --- a/etc/rc.d/routing +++ b/etc/rc.d/routing @@ -6,7 +6,7 @@ # # PROVIDE: routing -# REQUIRE: netif ppp-user +# REQUIRE: netif ppp . /etc/rc.subr diff --git a/etc/rc.d/rpcbind b/etc/rc.d/rpcbind index 3a2f14bfe0..768f05f55d 100644 --- a/etc/rc.d/rpcbind +++ b/etc/rc.d/rpcbind @@ -2,11 +2,10 @@ # # $NetBSD: rpcbind,v 1.6 2002/01/31 01:26:06 lukem Exp $ # $FreeBSD: src/etc/rc.d/rpcbind,v 1.6 2002/09/06 16:18:05 gordon Exp $ -# $DragonFly: src/etc/rc.d/rpcbind,v 1.4 2008/02/17 19:51:53 swildner Exp $ # # PROVIDE: rpcbind -# REQUIRE: NETWORKING syslogd named ppp +# REQUIRE: NETWORKING syslogd named . /etc/rc.subr diff --git a/include/Makefile b/include/Makefile index 0f42e70264..3f67f61fe5 100644 --- a/include/Makefile +++ b/include/Makefile @@ -64,7 +64,7 @@ LSUBDIRS= \ dev/video/bktr dev/video/meteor \ gnu/vfs/ext2fs \ libprop \ - net/bridge net/tap net/tun net/ppp net/ppp_layer net/sl \ + net/bridge net/tap net/tun net/ppp_layer net/sl \ net/pf net/altq \ net/vlan net/ipfw net/ip6fw net/dummynet net/sppp net/ip_mroute \ net/lagg \ diff --git a/lib/libc/net/getnameinfo.c b/lib/libc/net/getnameinfo.c index a4ae67708a..fb79944c9d 100644 --- a/lib/libc/net/getnameinfo.c +++ b/lib/libc/net/getnameinfo.c @@ -401,7 +401,7 @@ getnameinfo_link(const struct sockaddr *sa, socklen_t salen __unused, * IFT_FAITH (net/faith/if_faith.c) * IFT_GIF (net/gif/if_gif.c) * IFT_LOOP (net/if_loop.c, net/disc/if_disc.c) - * IFT_PPP (net/ppp/if_ppp.c, net/sppp/if_spppsubr.c) + * IFT_PPP (net/sppp/if_spppsubr.c) * IFT_SLIP (net/sl/if_sl.c) * IFT_STF (net/stf/if_stf.c) * IFT_L2VLAN (net/vlan/if_vlan.c) diff --git a/libexec/bootpd/syslog.conf b/libexec/bootpd/syslog.conf index 2c135af497..42bae0bdc9 100644 --- a/libexec/bootpd/syslog.conf +++ b/libexec/bootpd/syslog.conf @@ -58,6 +58,6 @@ user.alert `root, operator' user.emerg * ) -# Local2: (bootpd, pppd) +# Local2: (bootpd) local2.debug /dev/console #local2.debug /var/log/local2 diff --git a/share/examples/pppd/auth-down.sample b/share/examples/pppd/auth-down.sample deleted file mode 100644 index b4675df53d..0000000000 --- a/share/examples/pppd/auth-down.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# $FreeBSD: src/share/examples/pppd/auth-down.sample,v 1.1.2.1 2002/02/12 00:49:12 cjc Exp $ -# $DragonFly: src/share/examples/pppd/auth-down.sample,v 1.2 2003/06/17 04:36:57 dillon Exp $ -# -# Example for /etc/ppp/auth-down file. - -/usr/bin/logger -p daemon.notice -t pppd "User $2 is logged off" diff --git a/share/examples/pppd/auth-up.sample b/share/examples/pppd/auth-up.sample deleted file mode 100644 index 92ac86cc89..0000000000 --- a/share/examples/pppd/auth-up.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# $FreeBSD: src/share/examples/pppd/auth-up.sample,v 1.1.2.1 2002/02/12 00:49:12 cjc Exp $ -# $DragonFly: src/share/examples/pppd/auth-up.sample,v 1.2 2003/06/17 04:36:57 dillon Exp $ -# -# Example for /etc/ppp/auth-up file. - -/usr/bin/logger -p daemon.notice -t pppd "User $2 is logged in" diff --git a/share/examples/pppd/chap-secrets.sample b/share/examples/pppd/chap-secrets.sample deleted file mode 100644 index d76a83e449..0000000000 --- a/share/examples/pppd/chap-secrets.sample +++ /dev/null @@ -1,18 +0,0 @@ -# $FreeBSD: src/share/examples/pppd/chap-secrets.sample,v 1.1.2.1 2002/02/12 00:49:12 cjc Exp $ -# $DragonFly: src/share/examples/pppd/chap-secrets.sample,v 1.2 2003/06/17 04:36:57 dillon Exp $ -# -# Example for /etc/ppp/chap-secrets file. -# -# This file should be owned by root and not readable or -# writable by any other user. -# -# Dialin format: -# -joe server password 192.168.0.0/24 192.168.2.2 -lisa server l1z4 * !192.168.0.1 -mike server secret * -luser server nopass - -# -# Dialout format: -# -jane isp password diff --git a/share/examples/pppd/chat.sh.sample b/share/examples/pppd/chat.sh.sample deleted file mode 100644 index 92191c1851..0000000000 --- a/share/examples/pppd/chat.sh.sample +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh -# -# $FreeBSD: src/share/examples/pppd/chat.sh.sample,v 1.1.2.1 2002/02/12 00:49:12 cjc Exp $ -# $DragonFly: src/share/examples/pppd/chat.sh.sample,v 1.2 2003/06/17 04:36:57 dillon Exp $ -# -# Example for chat.sh file. - -INIT='at&f' - -dial(){ - /usr/bin/chat -v \ - ABORT "ERROR" \ - ABORT "NO DIALTONE" \ - TIMEOUT 5 \ - "" "AT" \ - "OK" "${INIT}" \ - "OK"-"+++"-"" "ATH" \ - ABORT "BUSY" \ - ABORT "NO ANSWER" \ - ABORT "NO CARRIER" \ - "OK" "ATDP$1" \ - TIMEOUT 70 \ - "ogin:" "username" \ - "word:" "pasword" \ - TIMEOUT 50 \ - "PPP" "\c" - - [ $? -eq 0 ] && exit 0 - - echo "$1 failed" 1>&2 - exit 1 -} - -dial 1234567 diff --git a/share/examples/pppd/ip-down.sample b/share/examples/pppd/ip-down.sample deleted file mode 100644 index 6b9483ac8f..0000000000 --- a/share/examples/pppd/ip-down.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# $FreeBSD: src/share/examples/pppd/ip-down.sample,v 1.1.2.1 2002/02/12 00:49:12 cjc Exp $ -# $DragonFly: src/share/examples/pppd/ip-down.sample,v 1.2 2003/06/17 04:36:57 dillon Exp $ -# -# Example for /etc/ppp/ip-down file. - -/usr/bin/logger -p daemon.notice -t pppd "$1 is down" diff --git a/share/examples/pppd/ip-up.sample b/share/examples/pppd/ip-up.sample deleted file mode 100644 index 82c73b620f..0000000000 --- a/share/examples/pppd/ip-up.sample +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -# -# $FreeBSD: src/share/examples/pppd/ip-up.sample,v 1.1.2.1 2002/02/12 00:49:12 cjc Exp $ -# $DragonFly: src/share/examples/pppd/ip-up.sample,v 1.3 2005/01/11 19:14:58 swildner Exp $ -# -# Example for /etc/ppp/ip-up file. - -/usr/bin/logger -p daemon.notice -t pppd "$1 is up" -/usr/sbin/rdate ntpserver diff --git a/share/examples/pppd/options.sample b/share/examples/pppd/options.sample deleted file mode 100644 index 2cfc9cdf22..0000000000 --- a/share/examples/pppd/options.sample +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD: src/share/examples/pppd/options.sample,v 1.1.2.1 2002/02/12 00:49:12 cjc Exp $ -# $DragonFly: src/share/examples/pppd/options.sample,v 1.2 2003/06/17 04:36:57 dillon Exp $ -# -# Example for /etc/ppp/options file. -# -/dev/cuaa4 -115200 -modem -crtscts -asyncmap 0 -connect '/etc/ppp/chat.sh' -defaultroute -noipdefault -persist -holdoff 5 -mtu 250 -mru 250 diff --git a/share/examples/pppd/pap-secrets.sample b/share/examples/pppd/pap-secrets.sample deleted file mode 100644 index 2dfd11af54..0000000000 --- a/share/examples/pppd/pap-secrets.sample +++ /dev/null @@ -1,18 +0,0 @@ -# $FreeBSD: src/share/examples/pppd/pap-secrets.sample,v 1.1.2.1 2002/02/12 00:49:12 cjc Exp $ -# $DragonFly: src/share/examples/pppd/pap-secrets.sample,v 1.2 2003/06/17 04:36:57 dillon Exp $ -# -# Example for /etc/ppp/pap-secrets file. -# -# This file should be owned by root and not readable or -# writable by any other user. -# -# Dialin format: -# -joe server password 192.168.0.1/24 192.168.2.2 -lisa server l1z4 * !192.168.0.1 -mike server secret * -luser server nopass - -# -# Dialout format: -# -jane isp password diff --git a/share/examples/pppd/ppp.deny.sample b/share/examples/pppd/ppp.deny.sample deleted file mode 100644 index 8833808bc9..0000000000 --- a/share/examples/pppd/ppp.deny.sample +++ /dev/null @@ -1,26 +0,0 @@ -# $FreeBSD: src/share/examples/pppd/ppp.deny.sample,v 1.5.2.3 2002/06/30 18:23:00 maxim Exp $ -# $DragonFly: src/share/examples/pppd/ppp.deny.sample,v 1.2 2003/06/17 04:36:57 dillon Exp $ -# -# list of users disallowed any pppd access via 'system -# password login'. -# read by pppd(8). -root -toor -daemon -operator -bin -tty -kmem -games -news -man -sshd -smmsp -mailnull -bind -ftp -uucp -xten -pop -www -nobody diff --git a/share/examples/pppd/ppp.shells.sample b/share/examples/pppd/ppp.shells.sample deleted file mode 100644 index a4682a8333..0000000000 --- a/share/examples/pppd/ppp.shells.sample +++ /dev/null @@ -1,15 +0,0 @@ -# $FreeBSD: src/share/examples/pppd/ppp.shells.sample,v 1.5.2.1 2002/02/12 00:49:12 cjc Exp $ -# $DragonFly: src/share/examples/pppd/ppp.shells.sample,v 1.2 2003/06/17 04:36:57 dillon Exp $ -# -# List of acceptable shells for pppd(8). -# Pppd will not accept a system password login -# by a user whose shell is not listed below. - -/bin/sh -/bin/csh -/bin/tcsh -/usr/local/bin/ksh -/usr/local/bin/zsh -/usr/local/bin/bash -/usr/local/bin/tcsh -/usr/local/bin/ppplogin.sh diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index f0b3ceda96..79b698a8b9 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -245,7 +245,6 @@ MAN= aac.4 \ ppbus.4 \ ppc.4 \ ppi.4 \ - ppp.4 \ psm.4 \ pt.4 \ pty.4 \ @@ -490,7 +489,6 @@ MLINKS+=oce.4 if_oce.4 MLINKS+=pccbb.4 cbb.4 MLINKS+=pcm.4 sound.4 MLINKS+=pcn.4 if_pcn.4 -MLINKS+=ppp.4 if_ppp.4 MLINKS+=radeonkms.4 radeon.4 \ radeonkms.4 radeondrm.4 MLINKS+=ral.4 if_ral.4 diff --git a/share/man/man4/ppp.4 b/share/man/man4/ppp.4 deleted file mode 100644 index bd4156b1c7..0000000000 --- a/share/man/man4/ppp.4 +++ /dev/null @@ -1,69 +0,0 @@ -.\" $NetBSD: ppp.4,v 1.1 1996/08/10 21:26:12 explorer Exp $ -.\" -.\" Copyright (c) 1983, 1991, 1993 -.\" The Regents of the University of California. 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. 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. -.\" -.\" From: @(#)lo.4 8.1 (Berkeley) 6/5/93 -.\" $FreeBSD: src/share/man/man4/ppp.4,v 1.4.2.1 2000/12/08 14:59:07 ru Exp $ -.\" $DragonFly: src/share/man/man4/ppp.4,v 1.2 2003/06/17 04:36:59 dillon Exp $ -.\" -.Dd August 10, 1996 -.Dt PPP 4 -.Os -.Sh NAME -.Nm ppp -.Nd point to point protocol network interface -.Sh SYNOPSIS -.Cd "pseudo-device ppp" Op Ar count -.Sh DESCRIPTION -The -.Nm -interface allows serial lines to be used as network interfaces using the -.Em point-to-point -protocol. The -.Nm -interface can use various types of compression and has many features over -the -.Xr sl 4 -protocol. -.Sh DIAGNOSTICS -.Bl -diag -.It ppp%d: af%d not supported. -The interface was handed -a message with addresses formatted in an unsuitable address -family; the packet was dropped. -.El -.Sh SEE ALSO -.Xr inet 4 , -.Xr intro 4 , -.Xr sl 4 , -.Xr pppd 8 , -.Xr pppstats 8 -.Sh BUGS -Currently, only the -.Xr ip 4 -protocol is supported. diff --git a/share/man/man4/sppp.4 b/share/man/man4/sppp.4 index 6aceebea3b..3d08cbc3d9 100644 --- a/share/man/man4/sppp.4 +++ b/share/man/man4/sppp.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD: src/share/man/man4/sppp.4,v 1.8.2.5 2002/04/24 18:55:35 joerg Exp $ .\" -.Dd December 30, 2001 +.Dd October 17, 2017 .Dt SPPP 4 .Os .Sh NAME @@ -158,7 +158,6 @@ take place. .Sh SEE ALSO .Xr inet 4 , .Xr intro 4 , -.Xr ppp 4 , .Xr ifconfig 8 , .Xr spppcontrol 8 .Rs diff --git a/share/man/man4/ugensa.4 b/share/man/man4/ugensa.4 index eaf972a5af..6db931b412 100644 --- a/share/man/man4/ugensa.4 +++ b/share/man/man4/ugensa.4 @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd February 21, 2008 +.Dd October 17, 2017 .Dt UGENSA 4 .Os .Sh NAME @@ -58,9 +58,7 @@ Communication devices supported by the .Nm driver typically have more than one virtual serial port, but only one of them (usually the first one) can be used with -.Xr ppp 8 -or -.Xr pppd 8 . +.Xr ppp 8 . At least one of additional ports can usually be used for device/network monitoring and other communication tasks (like SMS for example). Protocols and methods used to access these features are out of scope of this @@ -127,8 +125,7 @@ list is certainly incomplete. .Xr tty 4 , .Xr ucom 4 , .Xr usb 4 , -.Xr ppp 8 , -.Xr pppd 8 +.Xr ppp 8 .Sh HISTORY The .Nm diff --git a/share/man/man8/rc.8 b/share/man/man8/rc.8 index 47d3d4e98d..5b6007d554 100644 --- a/share/man/man8/rc.8 +++ b/share/man/man8/rc.8 @@ -31,7 +31,7 @@ .\" @(#)rc.8 8.2 (Berkeley) 12/11/93 .\" $FreeBSD: src/share/man/man8/rc.8,v 1.22 2002/12/12 17:25:58 ru Exp $ .\" -.Dd October 14, 2017 +.Dd October 17, 2017 .Dt RC 8 .Os .Sh NAME @@ -188,7 +188,7 @@ In order of startup, these are: .It Pa NETWORKING Ensure basic network services are running, including general network configuration -.Pq Pa netif , routing , network_ipv6 , ppp-user . +.Pq Pa netif , routing , network_ipv6 , ppp . .It Pa SERVERS Ensure basic services (such as .Pa NETWORKING diff --git a/share/man/man9/ioctl.9 b/share/man/man9/ioctl.9 index fdd66c675d..cd684d66f3 100644 --- a/share/man/man9/ioctl.9 +++ b/share/man/man9/ioctl.9 @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd August 10, 2015 +.Dd October 17, 2017 .Dt IOCTL 9 .Os .Sh NAME @@ -150,8 +150,6 @@ random number generator .It 't' .Xr tty 4 .It 't' -.Xr ppp 4 -.It 't' .Xr tap 4 .It 't' .Xr tun 4 diff --git a/sys/boot/dloader/loader-bootp.conf b/sys/boot/dloader/loader-bootp.conf index 689929ab71..a22d94223c 100644 --- a/sys/boot/dloader/loader-bootp.conf +++ b/sys/boot/dloader/loader-bootp.conf @@ -145,7 +145,6 @@ if_ef_load="NO" # pseudo-device providing support for multiple ethernet frame if_faith_load="NO" # IPv6-to-IPv4 TCP relay capturing interface if_gif_load="NO" # generic tunnel interface if_gre_load="NO" # encapsulating network device -if_ppp_load="NO" # Kernel ppp if_sl_load="NO" # SLIP if_stf_load="NO" # 6to4 tunnel interface if_tap_load="NO" # Ethernet tunnel software network interface diff --git a/sys/boot/dloader/loader.conf b/sys/boot/dloader/loader.conf index f1a7b28df7..08ce18daec 100644 --- a/sys/boot/dloader/loader.conf +++ b/sys/boot/dloader/loader.conf @@ -153,7 +153,6 @@ if_ef_load="NO" # pseudo-device providing support for multiple ethernet frame if_faith_load="NO" # IPv6-to-IPv4 TCP relay capturing interface if_gif_load="NO" # generic tunnel interface if_gre_load="NO" # encapsulating network device -if_ppp_load="NO" # Kernel ppp if_sl_load="NO" # SLIP if_stf_load="NO" # 6to4 tunnel interface if_tap_load="NO" # Ethernet tunnel software network interface diff --git a/sys/conf/files b/sys/conf/files index c782ee3a59..ce2a35fdf1 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1520,7 +1520,6 @@ net/bpf.c standard net/bpf_filter.c optional bpf net/bridge/if_bridge.c optional bridge net/bridge/bridgestp.c optional bridge -net/bsd_comp.c optional ppp_bsdcomp net/if.c standard net/if_clone.c standard net/if_poll.c optional ifpoll_enable @@ -1542,15 +1541,11 @@ net/pf/pf_norm.c optional pf net/pf/pf_ruleset.c optional pf net/pf/pf_table.c optional pf net/pf/pf_osfp.c optional pf -net/ppp_layer/slcompress.c optional ppp net/ppp_layer/slcompress.c optional sl net/ppp_layer/slcompress.c optional sppp -net/ppp_layer/ppp_deflate.c optional ppp_deflate -net/ppp_layer/ppp_tty.c optional ppp net/if_loop.c optional loop net/if_media.c standard net/if_mib.c standard -net/ppp/if_ppp.c optional ppp net/sl/if_sl.c optional sl net/sppp/if_spppsubr.c optional sppp net/stf/if_stf.c optional stf @@ -1565,7 +1560,6 @@ net/raw_cb.c standard net/raw_usrreq.c standard net/route.c standard net/rtsock.c standard -net/zlib.c optional ppp_deflate net/zlib.c optional ipsec netbt/bt_input.c optional bluetooth netbt/bt_proto.c optional bluetooth diff --git a/sys/conf/options b/sys/conf/options index 33d24278dc..7a8ad3f14e 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -250,9 +250,6 @@ IPV6FIREWALL_DEFAULT_TO_ACCEPT opt_ip6fw.h IPSTEALTH LIBMCHAIN MPLS opt_mpls.h -PPP_BSDCOMP opt_ppp.h -PPP_DEFLATE opt_ppp.h -PPP_FILTER opt_ppp.h TCPDEBUG TCP_SIGNATURE opt_inet.h TCP_DROP_SYNFIN opt_tcp_input.h diff --git a/sys/config/LINT64 b/sys/config/LINT64 index 9f42a5e513..0fe6ea893a 100644 --- a/sys/config/LINT64 +++ b/sys/config/LINT64 @@ -306,7 +306,6 @@ device mn # Munich32x/Falc54 Nx64kbit/sec cards. # The `sppp' pseudo-device serves a similar role for certain types # of synchronous PPP links. # The `sl' pseudo-device implements the Serial Line IP (SLIP) service. -# The `ppp' pseudo-device implements the Point-to-Point Protocol. # The `bpf' pseudo-device enables the Berkeley Packet Filter. Be # aware of the legal and administrative consequences of enabling this # option. The number of devices determines the maximum number of @@ -326,12 +325,6 @@ device mn # Munich32x/Falc54 Nx64kbit/sec cards. # The `ef' pseudo-device provides support for multiple ethernet frame types # specified via ETHER_* options. See ef(4) for details. # -# The PPP_BSDCOMP option enables support for compress(1) style entire -# packet compression, the PPP_DEFLATE is for zlib/gzip style compression. -# PPP_FILTER enables code for filtering the ppp data stream and selecting -# events for resetting the demand dial activity timer - requires bpf. -# See pppd(8) for more details. -# pseudo-device ether #Generic Ethernet pseudo-device vlan 1 #VLAN support pseudo-device bridge #Bridging support @@ -343,10 +336,6 @@ pseudo-device tap #Ethernet tunnel network interface pseudo-device tun #Tunnel driver (ppp(8), nos-tun(8)) pseudo-device sl 2 #Serial Line IP pseudo-device gre #IP over IP tunneling -pseudo-device ppp 2 #Point-to-point protocol -options PPP_BSDCOMP #PPP BSD-compress support -options PPP_DEFLATE #PPP zlib/deflate/gzip support -options PPP_FILTER #enable bpf filtering (needs bpf) # for IPv6 pseudo-device gif #IPv6 and IPv4 tunneling diff --git a/sys/net/Makefile b/sys/net/Makefile index caec824eef..8862bbf01b 100644 --- a/sys/net/Makefile +++ b/sys/net/Makefile @@ -1,7 +1,7 @@ SUBDIR=accf_data accf_http disc faith gif gre sl stf tap tun \ vlan zlib bridge lagg libalias dummynet ipfw \ dummynet3 ipfw3 ipfw3_basic ipfw3_nat ipfw3_layer2 ipfw3_layer4 \ - ip6fw ip_mroute sppp ppp_layer pf + ip6fw ip_mroute sppp pf # empty to allow concurrent building # diff --git a/sys/net/bsd_comp.c b/sys/net/bsd_comp.c deleted file mode 100644 index 47d47f7a2e..0000000000 --- a/sys/net/bsd_comp.c +++ /dev/null @@ -1,1085 +0,0 @@ -/* 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. 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 mbufs on BSD-derived systems. - * - * $FreeBSD: src/sys/net/bsd_comp.c,v 1.11.2.1 2002/04/14 21:41:48 luigi Exp $ - */ - -#include -#include -#include -#include -#include - -#define PACKETPTR struct mbuf * -#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_int16_t seqno; /* sequence # 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_int16_t *lens; /* array of lengths of codes */ - struct bsd_dict { - union { /* hash value */ - u_int32_t fcode; - struct { -#if BYTE_ORDER == LITTLE_ENDIAN - u_int16_t 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_int16_t prefix; /* preceding code */ -#endif - } hs; - } f; - u_int16_t codem1; /* output of hash table -1 */ - u_int16_t 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_clear (struct bsd_db *db); -static int bsd_check (struct bsd_db *db); -static void *bsd_alloc (u_char *options, int opt_len, int decomp); -static int bsd_init (struct bsd_db *db, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug, - int decomp); -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, struct mbuf **mret, - struct mbuf *mp, int slen, int maxolen); -static void bsd_incomp (void *state, struct mbuf *dmsg); -static int bsd_decompress (void *state, struct mbuf *cmp, - struct mbuf **dmpp); -static void bsd_reset (void *state); -static void bsd_comp_stats (void *state, struct compstat *stats); - -/* - * Procedures exported to if_ppp.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) - -/* - * 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. - * - * Return 1=output CLEAR - */ -static int -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; - 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(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 < CILEN_BSD_COMPRESS || options[0] != CI_BSD_COMPRESS - || options[1] != CILEN_BSD_COMPRESS - || 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 = kmalloc(newlen, M_DEVBUF, M_WAITOK); - bzero(db, sizeof(*db) - sizeof(db->dict)); - - if (!decomp) { - db->lens = NULL; - } else { - db->lens = kmalloc((maxmaxcode + 1) * sizeof(db->lens[0]), M_DEVBUF, - M_WAITOK); - } - - 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) - kfree(db->lens, M_DEVBUF); - kfree(db, M_DEVBUF); -} - -static void * -bsd_comp_alloc(u_char *options, int opt_len) -{ - return bsd_alloc(options, opt_len, 0); -} - -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; -#ifndef DEBUG - if (debug) -#endif - db->debug = 1; - - bsd_reset(db); - - return 1; -} - -static int -bsd_comp_init(void *state, u_char *options, int opt_len, int unit, - int hdrlen, int debug) -{ - return bsd_init((struct bsd_db *) state, options, opt_len, - unit, hdrlen, 0, debug, 0); -} - -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); -} - - -/* - * 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. - * **mret - return compressed mbuf chain here - * *mp - from here - * slen - uncompressed length - * maxolen - max compressed length - * - * return new slen - */ -static int -bsd_compress(void *state, struct mbuf **mret, struct mbuf *mp, - int slen, int maxolen) -{ - 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; - u_char *rptr, *wptr; - u_char *cp_end; - int olen; - struct mbuf *m; - -#define PUTBYTE(v) { \ - ++olen; \ - if (wptr) { \ - *wptr++ = (v); \ - if (wptr >= cp_end) { \ - m->m_len = wptr - mtod(m, u_char *); \ - MGET(m->m_next, M_NOWAIT, MT_DATA); \ - m = m->m_next; \ - if (m) { \ - m->m_len = 0; \ - if (maxolen - olen > MLEN) \ - MCLGET(m, M_NOWAIT); \ - wptr = mtod(m, u_char *); \ - cp_end = wptr + M_TRAILINGSPACE(m); \ - } else \ - wptr = NULL; \ - } \ - } \ -} - -#define OUTPUT(ent) { \ - bitno -= n_bits; \ - accm |= ((ent) << bitno); \ - do { \ - PUTBYTE(accm >> 24); \ - accm <<= 8; \ - bitno += 8; \ - } while (bitno <= 24); \ -} - - /* - * If the protocol is not in the range we're interested in, - * just return without compressing the packet. If it is, - * the protocol becomes the first byte to compress. - */ - rptr = mtod(mp, u_char *); - ent = PPP_PROTOCOL(rptr); - if (ent < 0x21 || ent > 0xf9) { - *mret = NULL; - return slen; - } - - /* Don't generate compressed packets which are larger than - the uncompressed packet. */ - if (maxolen > slen) - maxolen = slen; - - /* Allocate one mbuf to start with. */ - MGET(m, M_NOWAIT, MT_DATA); - *mret = m; - if (m != NULL) { - m->m_len = 0; - if (maxolen + db->hdrlen > MLEN) - MCLGET(m, M_NOWAIT); - m->m_data += db->hdrlen; - wptr = mtod(m, u_char *); - cp_end = wptr + M_TRAILINGSPACE(m); - } else - wptr = cp_end = NULL; - - /* - * Copy the PPP header over, changing the protocol, - * and install the 2-byte packet sequence number. - */ - if (wptr) { - *wptr++ = PPP_ADDRESS(rptr); /* assumes the ppp header is */ - *wptr++ = PPP_CONTROL(rptr); /* all in one mbuf */ - *wptr++ = 0; /* change the protocol */ - *wptr++ = PPP_COMP; - *wptr++ = db->seqno >> 8; - *wptr++ = db->seqno; - } - ++db->seqno; - - olen = 0; - rptr += PPP_HDRLEN; - slen = mp->m_len - PPP_HDRLEN; - ilen = slen + 1; - for (;;) { - if (slen <= 0) { - mp = mp->m_next; - if (!mp) - break; - rptr = mtod(mp, u_char *); - slen = mp->m_len; - 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); - - if (m != NULL) { - m->m_len = wptr - mtod(m, u_char *); - m->m_next = NULL; - } - - /* - * 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) { - /* throw away the compressed stuff if it is longer than uncompressed */ - if (*mret != NULL) { - m_freem(*mret); - *mret = NULL; - } - ++db->incomp_count; - db->incomp_bytes += ilen; - } else { - ++db->comp_count; - db->comp_bytes += olen + BSD_OVHD; - } - - 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(void *state, struct mbuf *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; - u_int32_t hval, disp; - int slen, ilen; - u_int bitno = 7; - u_char *rptr; - u_int ent; - - /* - * If the protocol is not in the range we're interested in, - * just return without looking at the packet. If it is, - * the protocol becomes the first byte to "compress". - */ - rptr = mtod(dmsg, u_char *); - ent = PPP_PROTOCOL(rptr); - if (ent < 0x21 || ent > 0xf9) - return; - - db->seqno++; - ilen = 1; /* count the protocol as 1 byte */ - rptr += PPP_HDRLEN; - slen = dmsg->m_len - PPP_HDRLEN; - for (;;) { - if (slen <= 0) { - dmsg = dmsg->m_next; - if (!dmsg) - break; - rptr = mtod(dmsg, u_char *); - slen = dmsg->m_len; - continue; - } - 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; - 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, struct mbuf *cmp, struct mbuf **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; - struct mbuf *m, *dmp, *mret; - int adrs, ctrl, ilen; - int space, codelen, extra; - - /* - * Save the address/control from the PPP header - * and then get the sequence number. - */ - *dmpp = NULL; - rptr = mtod(cmp, u_char *); - adrs = PPP_ADDRESS(rptr); - ctrl = PPP_CONTROL(rptr); - rptr += PPP_HDRLEN; - len = cmp->m_len - PPP_HDRLEN; - seq = 0; - for (i = 0; i < 2; ++i) { - while (len <= 0) { - cmp = cmp->m_next; - if (cmp == NULL) - return DECOMP_ERROR; - rptr = mtod(cmp, u_char *); - len = cmp->m_len; - } - seq = (seq << 8) + *rptr++; - --len; - } - - /* - * Check the sequence number and give up if it differs from - * the value we're expecting. - */ - if (seq != db->seqno) { - if (db->debug) - kprintf("bsd_decomp%d: bad sequence # %d, expected %d\n", - db->unit, seq, db->seqno - 1); - return DECOMP_ERROR; - } - ++db->seqno; - - /* - * Allocate one mbuf to start with. - */ - MGETHDR(dmp, M_NOWAIT, MT_DATA); - if (dmp == NULL) - return DECOMP_ERROR; - mret = dmp; - dmp->m_len = 0; - dmp->m_next = NULL; - MCLGET(dmp, M_NOWAIT); - dmp->m_data += db->hdrlen; - wptr = mtod(dmp, u_char *); - space = M_TRAILINGSPACE(dmp) - PPP_HDRLEN + 1; - - /* - * 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; - - ilen = len; - oldcode = CLEAR; - explen = 0; - for (;;) { - if (len == 0) { - cmp = cmp->m_next; - if (!cmp) /* quit at end of message */ - break; - rptr = mtod(cmp, u_char *); - len = cmp->m_len; - 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 mbuf at the end. - */ - if (len > 0 || cmp->m_next != NULL) { - while ((cmp = cmp->m_next) != NULL) - len += cmp->m_len; - if (len > 0) { - m_freem(mret); - if (db->debug) - kprintf("bsd_decomp%d: bad CLEAR\n", db->unit); - return DECOMP_FATALERROR; /* probably a bug */ - } - } - bsd_clear(db); - explen = ilen = 0; - break; - } - - if (incode > max_ent + 2 || incode > db->maxmaxcode - || (incode > max_ent && oldcode == CLEAR)) { - m_freem(mret); - if (db->debug) { - kprintf("bsd_decomp%d: bad code 0x%x oldcode=0x%x ", - db->unit, incode, oldcode); - kprintf("max_ent=0x%x explen=%d seqno=%d\n", - max_ent, explen, 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) { - m_freem(mret); - if (db->debug) { - kprintf("bsd_decomp%d: ran out of mru\n", db->unit); -#ifdef DEBUG - while ((cmp = cmp->m_next) != NULL) - len += cmp->m_len; - kprintf(" len=%d, finchar=0x%x, codelen=%d, explen=%d\n", - len, finchar, codelen, explen); -#endif - } - return DECOMP_FATALERROR; - } - - /* - * For simplicity, the decoded characters go in a single mbuf, - * so we allocate a single extra cluster mbuf if necessary. - */ - if ((space -= codelen + extra) < 0) { - dmp->m_len = wptr - mtod(dmp, u_char *); - MGET(m, M_NOWAIT, MT_DATA); - if (m == NULL) { - m_freem(mret); - return DECOMP_ERROR; - } - m->m_len = 0; - m->m_next = NULL; - dmp->m_next = m; - MCLGET(m, M_NOWAIT); - space = M_TRAILINGSPACE(m) - (codelen + extra); - if (space < 0) { - /* now that's what I call *compression*. */ - m_freem(mret); - return DECOMP_ERROR; - } - dmp = m; - wptr = mtod(dmp, u_char *); - } - - /* - * 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 - if (--codelen <= 0 || dictp->codem1 != finchar-1) - goto bad; -#endif - *--p = dictp->f.hs.suffix; - finchar = dictp->f.hs.prefix; - } - *--p = finchar; - -#ifdef DEBUG - if (--codelen != 0) - kprintf("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; - u_int32_t 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; - } - dmp->m_len = wptr - mtod(dmp, u_char *); - - /* - * 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) { - kprintf("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; - -#ifdef DEBUG - bad: - if (codelen <= 0) { - kprintf("bsd_decomp%d: fell off end of chain ", db->unit); - kprintf("0x%x at 0x%x by 0x%x, max_ent=0x%x\n", - incode, finchar, db->dict[finchar].cptr, max_ent); - } else if (dictp->codem1 != finchar-1) { - kprintf("bsd_decomp%d: bad code chain 0x%x finchar=0x%x ", - db->unit, incode, finchar); - kprintf("oldcode=0x%x cptr=0x%x codem1=0x%x\n", oldcode, - db->dict[finchar].cptr, dictp->codem1); - } - m_freem(mret); - return DECOMP_FATALERROR; -#endif /* DEBUG */ -} -#endif /* DO_BSD_COMPRESS */ diff --git a/sys/net/ppp/if_ppp.c b/sys/net/ppp/if_ppp.c deleted file mode 100644 index 175bd4a241..0000000000 --- a/sys/net/ppp/if_ppp.c +++ /dev/null @@ -1,1577 +0,0 @@ -/* - * if_ppp.c - Point-to-Point Protocol (PPP) Asynchronous driver. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * Drew D. Perkins - * Carnegie Mellon University - * 4910 Forbes Ave. - * Pittsburgh, PA 15213 - * (412) 268-8576 - * ddp@andrew.cmu.edu - * - * Based on: - * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89 - * - * Copyright (c) 1987 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. - * - * Serial Line interface - * - * Rick Adams - * Center for Seismic Studies - * 1300 N 17th Street, Suite 1450 - * Arlington, Virginia 22209 - * (703)276-7900 - * rick@seismo.ARPA - * seismo!rick - * - * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris). - * Converted to 4.3BSD Beta by Chris Torek. - * Other changes made at Berkeley, based in part on code by Kirk Smith. - * - * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com) - * Added VJ tcp header compression; more unified ioctls - * - * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au). - * Cleaned up a lot of the mbuf-related code to fix bugs that - * caused system crashes and packet corruption. Changed pppstart - * so that it doesn't just give up with a collision if the whole - * packet doesn't fit in the output ring buffer. - * - * Added priority queueing for interactive IP packets, following - * the model of if_sl.c, plus hooks for bpf. - * Paul Mackerras (paulus@cs.anu.edu.au). - */ - -/* $FreeBSD: src/sys/net/if_ppp.c,v 1.67.2.4 2002/04/14 21:41:48 luigi Exp $ */ -/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ -/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */ - -#include "use_ppp.h" - -#include "opt_inet.h" -#include "opt_ppp.h" - -#ifdef INET -#define VJC -#endif -#define PPP_COMPRESS - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#ifdef INET -#include -#include -#include -#include -#endif - -#ifdef VJC -#include -#endif - -#include "if_ppp.h" -#include "if_pppvar.h" - -/* minimise diffs */ -#ifndef splsoftnet -#define splsoftnet splnet -#endif - -#ifdef PPP_COMPRESS -#define PACKETPTR struct mbuf * -#include -#endif - -struct ppp_softc ppp_softc[NPPP]; - -/* XXX layering violation */ -extern void pppasyncattach (void *); - -static void pppattach (void *); -PSEUDO_SET(pppattach, if_ppp); - -static int pppsioctl (struct ifnet *ifp, u_long cmd, caddr_t data, - struct ucred *); - -static void ppp_requeue (struct ppp_softc *); -static void ppp_ccp (struct ppp_softc *, struct mbuf *m, int rcvd); -static void ppp_ccp_closed (struct ppp_softc *); -static void ppp_inproc (struct ppp_softc *, struct mbuf *); -static void pppdumpm (struct mbuf *m0); -static void ppp_ifstart(struct ifnet *ifp, struct ifaltq_subque *ifsq); - -/* - * Some useful mbuf macros not in mbuf.h. - */ -#define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT) - -#define M_DATASTART(m) \ - (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \ - (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat) - -#define M_DATASIZE(m) \ - (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \ - (m)->m_flags & M_PKTHDR ? MHLEN: MLEN) - -/* - * We steal two bits in the mbuf m_flags, to mark high-priority packets - * for output, and received packets following lost/corrupted packets. - */ -#define M_HIGHPRI M_PROTO2 /* output packet for sc_fastq */ -#define M_ERRMARK M_PROTO3 /* steal a bit in mbuf m_flags */ - - -#ifdef PPP_COMPRESS -/* - * List of compressors we know about. - * We leave some space so maybe we can modload compressors. - */ - -extern struct compressor ppp_bsd_compress; -extern struct compressor ppp_deflate, ppp_deflate_draft; - -static struct compressor *ppp_compressors[8] = { -#if DO_BSD_COMPRESS && defined(PPP_BSDCOMP) - &ppp_bsd_compress, -#endif -#if DO_DEFLATE && defined(PPP_DEFLATE) - &ppp_deflate, - &ppp_deflate_draft, -#endif - NULL -}; -#endif /* PPP_COMPRESS */ - -/* - * Software interrupt routine, called at spl[soft]net. - */ -static void -pppintr(netmsg_t msg) -{ - struct mbuf *m; - struct ppp_softc *sc; - struct ifaltq_subque *ifsq; - int i; - - /* - * Packets are never sent to this netisr so the message must always - * be replied. Interlock processing and notification by replying - * the message first. - */ - lwkt_replymsg(&msg->lmsg, 0); - - get_mplock(); - - sc = ppp_softc; - ifsq = ifq_get_subq_default(&sc->sc_if.if_snd); - - for (i = 0; i < NPPP; ++i, ++sc) { - ifnet_serialize_all(&sc->sc_if); - if (!(sc->sc_flags & SC_TBUSY) - && (!ifsq_is_empty(ifsq) || !IF_QEMPTY(&sc->sc_fastq))) { - sc->sc_flags |= SC_TBUSY; - (*sc->sc_start)(sc); - } - for (;;) { - IF_DEQUEUE(&sc->sc_rawq, m); - if (m == NULL) - break; - ppp_inproc(sc, m); - } - ifnet_deserialize_all(&sc->sc_if); - } - rel_mplock(); -} - -/* - * Called from boot code to establish ppp interfaces. - */ -static void -pppattach(void *dummy) -{ - struct ppp_softc *sc; - int i = 0; - - for (sc = ppp_softc; i < NPPP; sc++) { - if_initname(&(sc->sc_if), "ppp", i++); - sc->sc_if.if_softc = sc; - sc->sc_if.if_mtu = PPP_MTU; - sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST; - sc->sc_if.if_type = IFT_PPP; - sc->sc_if.if_hdrlen = PPP_HDRLEN; - sc->sc_if.if_ioctl = pppsioctl; - sc->sc_if.if_output = pppoutput; - sc->sc_if.if_start = ppp_ifstart; - ifq_set_maxlen(&sc->sc_if.if_snd, IFQ_MAXLEN); - ifq_set_ready(&sc->sc_if.if_snd); - sc->sc_inq.ifq_maxlen = IFQ_MAXLEN; - sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN; - sc->sc_rawq.ifq_maxlen = IFQ_MAXLEN; - callout_init(&sc->sc_timeout); - if_attach(&sc->sc_if, NULL); - bpfattach(&sc->sc_if, DLT_PPP, PPP_HDRLEN); - } - netisr_register(NETISR_PPP, pppintr, NULL); - /* - * XXX layering violation - if_ppp can work over any lower level - * transport that cares to attach to it. - */ - pppasyncattach(dummy); -} - -/* - * Allocate a ppp interface unit and initialize it. - */ -struct ppp_softc * -pppalloc(struct thread *td) -{ - int nppp, i; - struct ppp_softc *sc; - - for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++) - if (sc->sc_xfer == td) { - sc->sc_xfer = NULL; - return sc; - } - for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++) - if (sc->sc_devp == NULL) - break; - if (nppp >= NPPP) - return NULL; - - sc->sc_flags = 0; - sc->sc_mru = PPP_MRU; - sc->sc_relinq = NULL; - bzero((char *)&sc->sc_stats, sizeof(sc->sc_stats)); -#ifdef VJC - sc->sc_comp = kmalloc(sizeof(struct slcompress), M_DEVBUF, M_WAITOK); - sl_compress_init(sc->sc_comp, -1); -#endif -#ifdef PPP_COMPRESS - sc->sc_xc_state = NULL; - sc->sc_rc_state = NULL; -#endif /* PPP_COMPRESS */ - for (i = 0; i < NUM_NP; ++i) - sc->sc_npmode[i] = NPMODE_ERROR; - sc->sc_npqueue = NULL; - sc->sc_npqtail = &sc->sc_npqueue; - sc->sc_last_sent = sc->sc_last_recv = time_uptime; - - return sc; -} - -/* - * Deallocate a ppp unit. Must be called at splsoftnet or higher. - */ -void -pppdealloc(struct ppp_softc *sc) -{ - struct mbuf *m; - - if_down(&sc->sc_if); - sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING); - getmicrotime(&sc->sc_if.if_lastchange); - sc->sc_devp = NULL; - sc->sc_xfer = NULL; - for (;;) { - IF_DEQUEUE(&sc->sc_rawq, m); - if (m == NULL) - break; - m_freem(m); - } - for (;;) { - IF_DEQUEUE(&sc->sc_inq, m); - if (m == NULL) - break; - m_freem(m); - } - for (;;) { - IF_DEQUEUE(&sc->sc_fastq, m); - if (m == NULL) - break; - m_freem(m); - } - while ((m = sc->sc_npqueue) != NULL) { - sc->sc_npqueue = m->m_nextpkt; - m_freem(m); - } -#ifdef PPP_COMPRESS - ppp_ccp_closed(sc); - sc->sc_xc_state = NULL; - sc->sc_rc_state = NULL; -#endif /* PPP_COMPRESS */ -#ifdef PPP_FILTER - if (sc->sc_pass_filt.bf_insns != NULL) { - kfree(sc->sc_pass_filt.bf_insns, M_DEVBUF); - sc->sc_pass_filt.bf_insns = NULL; - sc->sc_pass_filt.bf_len = 0; - } - if (sc->sc_active_filt.bf_insns != NULL) { - kfree(sc->sc_active_filt.bf_insns, M_DEVBUF); - sc->sc_active_filt.bf_insns = NULL; - sc->sc_active_filt.bf_len = 0; - } -#endif /* PPP_FILTER */ -#ifdef VJC - if (sc->sc_comp != NULL) { - kfree(sc->sc_comp, M_DEVBUF); - sc->sc_comp = NULL; - } -#endif -} - -/* - * Ioctl routine for generic ppp devices. - */ -int -pppioctl(struct ppp_softc *sc, u_long cmd, caddr_t data, - int flag, struct ucred *cred) -{ - int error, flags, mru, npx; - u_int nb; - struct ppp_option_data *odp; - struct compressor **cp; - struct npioctl *npi; - time_t t; -#ifdef PPP_FILTER - struct bpf_program *bp, *nbp; - struct bpf_insn *newcode, *oldcode; - int newcodelen; -#endif /* PPP_FILTER */ -#ifdef PPP_COMPRESS - u_char ccp_option[CCP_MAX_OPTION_LENGTH]; -#endif - - switch (cmd) { - case FIONREAD: - *(int *)data = sc->sc_inq.ifq_len; - break; - - case PPPIOCGUNIT: - *(int *)data = sc->sc_if.if_dunit; - break; - - case PPPIOCGFLAGS: - *(u_int *)data = sc->sc_flags; - break; - - case PPPIOCSFLAGS: - if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0) - return (error); - flags = *(int *)data & SC_MASK; - crit_enter(); -#ifdef PPP_COMPRESS - if (sc->sc_flags & SC_CCP_OPEN && !(flags & SC_CCP_OPEN)) - ppp_ccp_closed(sc); -#endif - sc->sc_flags = (sc->sc_flags & ~SC_MASK) | flags; - crit_exit(); - break; - - case PPPIOCSMRU: - if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0) - return (error); - mru = *(int *)data; - if (mru >= PPP_MRU && mru <= PPP_MAXMRU) - sc->sc_mru = mru; - break; - - case PPPIOCGMRU: - *(int *)data = sc->sc_mru; - break; - -#ifdef VJC - case PPPIOCSMAXCID: - if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0) - return (error); - if (sc->sc_comp) { - crit_enter(); - sl_compress_init(sc->sc_comp, *(int *)data); - crit_exit(); - } - break; -#endif - - case PPPIOCXFERUNIT: - if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0) - return (error); - sc->sc_xfer = curthread; - break; - -#ifdef PPP_COMPRESS - case PPPIOCSCOMPRESS: - if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0) - return (error); - odp = (struct ppp_option_data *) data; - nb = odp->length; - if (nb > sizeof(ccp_option)) - nb = sizeof(ccp_option); - if ((error = copyin(odp->ptr, ccp_option, nb)) != 0) - return (error); - if (ccp_option[1] < 2) /* preliminary check on the length byte */ - return (EINVAL); - for (cp = ppp_compressors; *cp != NULL; ++cp) - if ((*cp)->compress_proto == ccp_option[0]) { - /* - * Found a handler for the protocol - try to allocate - * a compressor or decompressor. - */ - error = 0; - if (odp->transmit) { - crit_enter(); - if (sc->sc_xc_state != NULL) - (*sc->sc_xcomp->comp_free)(sc->sc_xc_state); - sc->sc_xcomp = *cp; - sc->sc_xc_state = (*cp)->comp_alloc(ccp_option, nb); - if (sc->sc_xc_state == NULL) { - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: comp_alloc failed\n", - sc->sc_if.if_xname); - error = ENOBUFS; - } - sc->sc_flags &= ~SC_COMP_RUN; - crit_exit(); - } else { - crit_enter(); - if (sc->sc_rc_state != NULL) - (*sc->sc_rcomp->decomp_free)(sc->sc_rc_state); - sc->sc_rcomp = *cp; - sc->sc_rc_state = (*cp)->decomp_alloc(ccp_option, nb); - if (sc->sc_rc_state == NULL) { - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: decomp_alloc failed\n", - sc->sc_if.if_xname); - error = ENOBUFS; - } - sc->sc_flags &= ~SC_DECOMP_RUN; - crit_exit(); - } - return (error); - } - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: no compressor for [%x %x %x], %x\n", - sc->sc_if.if_xname, ccp_option[0], ccp_option[1], - ccp_option[2], nb); - return (EINVAL); /* no handler found */ -#endif /* PPP_COMPRESS */ - - case PPPIOCGNPMODE: - case PPPIOCSNPMODE: - npi = (struct npioctl *) data; - switch (npi->protocol) { - case PPP_IP: - npx = NP_IP; - break; - default: - return EINVAL; - } - if (cmd == PPPIOCGNPMODE) { - npi->mode = sc->sc_npmode[npx]; - } else { - if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0) - return (error); - if (npi->mode != sc->sc_npmode[npx]) { - crit_enter(); - sc->sc_npmode[npx] = npi->mode; - if (npi->mode != NPMODE_QUEUE) { - ppp_requeue(sc); - (*sc->sc_start)(sc); - } - crit_exit(); - } - } - break; - - case PPPIOCGIDLE: - crit_enter(); - t = time_uptime; - ((struct ppp_idle *)data)->xmit_idle = t - sc->sc_last_sent; - ((struct ppp_idle *)data)->recv_idle = t - sc->sc_last_recv; - crit_exit(); - break; - -#ifdef PPP_FILTER - case PPPIOCSPASS: - case PPPIOCSACTIVE: - nbp = (struct bpf_program *) data; - if ((unsigned) nbp->bf_len > BPF_MAXINSNS) - return EINVAL; - newcodelen = nbp->bf_len * sizeof(struct bpf_insn); - if (newcodelen != 0) { - newcode = kmalloc(newcodelen, M_DEVBUF, M_WAITOK); - if ((error = copyin((caddr_t)nbp->bf_insns, (caddr_t)newcode, - newcodelen)) != 0) { - kfree(newcode, M_DEVBUF); - return error; - } - if (!bpf_validate(newcode, nbp->bf_len)) { - kfree(newcode, M_DEVBUF); - return EINVAL; - } - } else - newcode = NULL; - bp = (cmd == PPPIOCSPASS)? &sc->sc_pass_filt: &sc->sc_active_filt; - oldcode = bp->bf_insns; - crit_enter(); - bp->bf_len = nbp->bf_len; - bp->bf_insns = newcode; - crit_exit(); - if (oldcode != NULL) - kfree(oldcode, M_DEVBUF); - break; -#endif - - default: - return (ENOIOCTL); - } - return (0); -} - -/* - * Process an ioctl request to the ppp network interface. - */ -static int -pppsioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr) -{ - struct ppp_softc *sc = &ppp_softc[ifp->if_dunit]; - struct ifaddr *ifa = (struct ifaddr *)data; - struct ifreq *ifr = (struct ifreq *)data; - struct ppp_stats *psp; -#ifdef PPP_COMPRESS - struct ppp_comp_stats *pcp; -#endif - int error = 0; - - crit_enter(); - - switch (cmd) { - case SIOCSIFFLAGS: - if ((ifp->if_flags & IFF_RUNNING) == 0) - ifp->if_flags &= ~IFF_UP; - break; - - case SIOCSIFADDR: - case SIOCAIFADDR: - switch(ifa->ifa_addr->sa_family) { -#ifdef INET - case AF_INET: - break; -#endif - default: - error = EAFNOSUPPORT; - break; - } - break; - - case SIOCSIFDSTADDR: - switch(ifa->ifa_addr->sa_family) { -#ifdef INET - case AF_INET: - break; -#endif - default: - error = EAFNOSUPPORT; - break; - } - break; - - case SIOCSIFMTU: - if ((error = priv_check_cred(cr, PRIV_ROOT, 0)) != 0) - break; - if (ifr->ifr_mtu > PPP_MAXMTU) - error = EINVAL; - else { - sc->sc_if.if_mtu = ifr->ifr_mtu; - if (sc->sc_setmtu) - (*sc->sc_setmtu)(sc); - } - break; - - case SIOCGIFMTU: - ifr->ifr_mtu = sc->sc_if.if_mtu; - break; - - case SIOCADDMULTI: - case SIOCDELMULTI: - if (ifr == NULL) { - error = EAFNOSUPPORT; - break; - } - switch(ifr->ifr_addr.sa_family) { -#ifdef INET - case AF_INET: - break; -#endif - default: - error = EAFNOSUPPORT; - break; - } - break; - - case SIOCGPPPSTATS: - psp = &((struct ifpppstatsreq *) data)->stats; - bzero(psp, sizeof(*psp)); - psp->p = sc->sc_stats; -#if defined(VJC) && !defined(SL_NO_STATS) - if (sc->sc_comp) { - psp->vj.vjs_packets = sc->sc_comp->sls_packets; - psp->vj.vjs_compressed = sc->sc_comp->sls_compressed; - psp->vj.vjs_searches = sc->sc_comp->sls_searches; - psp->vj.vjs_misses = sc->sc_comp->sls_misses; - psp->vj.vjs_uncompressedin = sc->sc_comp->sls_uncompressedin; - psp->vj.vjs_compressedin = sc->sc_comp->sls_compressedin; - psp->vj.vjs_errorin = sc->sc_comp->sls_errorin; - psp->vj.vjs_tossed = sc->sc_comp->sls_tossed; - } -#endif /* VJC */ - break; - -#ifdef PPP_COMPRESS - case SIOCGPPPCSTATS: - pcp = &((struct ifpppcstatsreq *) data)->stats; - bzero(pcp, sizeof(*pcp)); - if (sc->sc_xc_state != NULL) - (*sc->sc_xcomp->comp_stat)(sc->sc_xc_state, &pcp->c); - if (sc->sc_rc_state != NULL) - (*sc->sc_rcomp->decomp_stat)(sc->sc_rc_state, &pcp->d); - break; -#endif /* PPP_COMPRESS */ - - default: - error = ENOTTY; - } - crit_exit(); - return (error); -} - -/* - * Queue a packet. Start transmission if not active. - * Packet is placed in Information field of PPP frame. - * Called at splnet as the if->if_output handler. - * Called at splnet from pppwrite(). - */ -static int -pppoutput_serialized(struct ifnet *ifp, struct ifaltq_subque *ifsq, - struct mbuf *m0, struct sockaddr *dst, struct rtentry *rtp) -{ - struct ppp_softc *sc = &ppp_softc[ifp->if_dunit]; - int protocol, address, control; - u_char *cp; - int error; -#ifdef INET - struct ip *ip; -#endif - struct ifqueue *ifq; - enum NPmode mode; - int len; - struct mbuf *m; - struct altq_pktattr pktattr; - - if (sc->sc_devp == NULL || (ifp->if_flags & IFF_RUNNING) == 0 - || ((ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC)) { - error = ENETDOWN; /* sort of */ - goto bad; - } - - ifq_classify(&ifp->if_snd, m0, dst->sa_family, &pktattr); - - /* - * Compute PPP header. - */ - m0->m_flags &= ~M_HIGHPRI; - switch (dst->sa_family) { -#ifdef INET - case AF_INET: - address = PPP_ALLSTATIONS; - control = PPP_UI; - protocol = PPP_IP; - mode = sc->sc_npmode[NP_IP]; - - /* - * If this packet has the "low delay" bit set in the IP header, - * put it on the fastq instead. - */ - ip = mtod(m0, struct ip *); - if (ip->ip_tos & IPTOS_LOWDELAY) - m0->m_flags |= M_HIGHPRI; - break; -#endif - case AF_UNSPEC: - address = PPP_ADDRESS(dst->sa_data); - control = PPP_CONTROL(dst->sa_data); - protocol = PPP_PROTOCOL(dst->sa_data); - mode = NPMODE_PASS; - break; - default: - kprintf("%s: af%d not supported\n", ifp->if_xname, dst->sa_family); - error = EAFNOSUPPORT; - goto bad; - } - - /* - * Drop this packet, or return an error, if necessary. - */ - if (mode == NPMODE_ERROR) { - error = ENETDOWN; - goto bad; - } - if (mode == NPMODE_DROP) { - error = 0; - goto bad; - } - - /* - * Add PPP header. If no space in first mbuf, allocate another. - * (This assumes M_LEADINGSPACE is always 0 for a cluster mbuf.) - */ - if (M_LEADINGSPACE(m0) < PPP_HDRLEN) { - m0 = m_prepend(m0, PPP_HDRLEN, M_NOWAIT); - if (m0 == NULL) { - error = ENOBUFS; - goto bad; - } - m0->m_len = 0; - } else - m0->m_data -= PPP_HDRLEN; - - cp = mtod(m0, u_char *); - *cp++ = address; - *cp++ = control; - *cp++ = protocol >> 8; - *cp++ = protocol & 0xff; - m0->m_len += PPP_HDRLEN; - - len = 0; - for (m = m0; m != NULL; m = m->m_next) - len += m->m_len; - - if (sc->sc_flags & SC_LOG_OUTPKT) { - kprintf("%s output: ", ifp->if_xname); - pppdumpm(m0); - } - - if ((protocol & 0x8000) == 0) { -#ifdef PPP_FILTER - /* - * Apply the pass and active filters to the packet, - * but only if it is a data packet. - */ - *mtod(m0, u_char *) = 1; /* indicates outbound */ - if (sc->sc_pass_filt.bf_insns != NULL - && bpf_filter(sc->sc_pass_filt.bf_insns, (u_char *) m0, - len, 0) == 0) { - error = 0; /* drop this packet */ - goto bad; - } - - /* - * Update the time we sent the most recent packet. - */ - if (sc->sc_active_filt.bf_insns == NULL - || bpf_filter(sc->sc_active_filt.bf_insns, (u_char *) m0, len, 0)) - sc->sc_last_sent = time_uptime; - - *mtod(m0, u_char *) = address; -#else - /* - * Update the time we sent the most recent data packet. - */ - sc->sc_last_sent = time_uptime; -#endif /* PPP_FILTER */ - } - - BPF_MTAP(ifp, m0); - - /* - * Put the packet on the appropriate queue. - */ - crit_enter(); - if (mode == NPMODE_QUEUE) { - /* XXX we should limit the number of packets on this queue */ - *sc->sc_npqtail = m0; - m0->m_nextpkt = NULL; - sc->sc_npqtail = &m0->m_nextpkt; - } else { - /* fastq and if_snd are emptied at spl[soft]net now */ - if ((m0->m_flags & M_HIGHPRI) && !ifq_is_enabled(&sc->sc_if.if_snd)) { - ifq = &sc->sc_fastq; - if (IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) { - IF_DROP(ifq); - m_freem(m0); - error = ENOBUFS; - } else { - IF_ENQUEUE(ifq, m0); - error = 0; - } - } else { - ASSERT_ALTQ_SQ_SERIALIZED_HW(ifsq); - error = ifsq_enqueue(ifsq, m0, &pktattr); - } - if (error) { - crit_exit(); - IFNET_STAT_INC(&sc->sc_if, oqdrops, 1); - sc->sc_stats.ppp_oerrors++; - return (error); - } - (*sc->sc_start)(sc); - } - getmicrotime(&ifp->if_lastchange); - IFNET_STAT_INC(ifp, opackets, 1); - IFNET_STAT_INC(ifp, obytes, len); - - crit_exit(); - return (0); - -bad: - m_freem(m0); - return (error); -} - -int -pppoutput(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, - struct rtentry *rtp) -{ - struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd); - int error; - - ifsq_serialize_hw(ifsq); - error = pppoutput_serialized(ifp, ifsq, m0, dst, rtp); - ifsq_deserialize_hw(ifsq); - - return error; -} - -/* - * After a change in the NPmode for some NP, move packets from the - * npqueue to the send queue or the fast queue as appropriate. - * Should be called at spl[soft]net. - */ -static void -ppp_requeue(struct ppp_softc *sc) -{ - struct mbuf *m, **mpp; - struct ifqueue *ifq; - struct ifaltq_subque *ifsq; - enum NPmode mode; - int error; - - ifsq = ifq_get_subq_default(&sc->sc_if.if_snd); - for (mpp = &sc->sc_npqueue; (m = *mpp) != NULL; ) { - switch (PPP_PROTOCOL(mtod(m, u_char *))) { - case PPP_IP: - mode = sc->sc_npmode[NP_IP]; - break; - default: - mode = NPMODE_PASS; - } - - switch (mode) { - case NPMODE_PASS: - /* - * This packet can now go on one of the queues to be sent. - */ - *mpp = m->m_nextpkt; - m->m_nextpkt = NULL; - if ((m->m_flags & M_HIGHPRI) && !ifq_is_enabled(&sc->sc_if.if_snd)) { - ifq = &sc->sc_fastq; - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - error = ENOBUFS; - } else { - IF_ENQUEUE(ifq, m); - error = 0; - } - } else { - error = ifsq_enqueue(ifsq, m, NULL); - } - if (error) { - IFNET_STAT_INC(&sc->sc_if, oqdrops, 1); - sc->sc_stats.ppp_oerrors++; - } - break; - - case NPMODE_DROP: - case NPMODE_ERROR: - *mpp = m->m_nextpkt; - m_freem(m); - break; - - case NPMODE_QUEUE: - mpp = &m->m_nextpkt; - break; - } - } - sc->sc_npqtail = mpp; -} - -/* - * Transmitter has finished outputting some stuff; - * remember to call sc->sc_start later at splsoftnet. - */ -void -ppp_restart(struct ppp_softc *sc) -{ - crit_enter(); - sc->sc_flags &= ~SC_TBUSY; - schednetisr(NETISR_PPP); - crit_exit(); -} - - -/* - * Get a packet to send. This procedure is intended to be called at - * splsoftnet, since it may involve time-consuming operations such as - * applying VJ compression, packet compression, address/control and/or - * protocol field compression to the packet. - */ -struct mbuf * -ppp_dequeue(struct ppp_softc *sc) -{ - struct mbuf *m, *mp; - u_char *cp; - int address, control, protocol; - - /* - * Grab a packet to send: first try the fast queue, then the - * normal queue. - */ - IF_DEQUEUE(&sc->sc_fastq, m); - if (m == NULL) - m = ifsq_dequeue(ifq_get_subq_default(&sc->sc_if.if_snd)); - if (m == NULL) - return NULL; - - ++sc->sc_stats.ppp_opackets; - - /* - * Extract the ppp header of the new packet. - * The ppp header will be in one mbuf. - */ - cp = mtod(m, u_char *); - address = PPP_ADDRESS(cp); - control = PPP_CONTROL(cp); - protocol = PPP_PROTOCOL(cp); - - switch (protocol) { - case PPP_IP: -#ifdef VJC - /* - * If the packet is a TCP/IP packet, see if we can compress it. - */ - if ((sc->sc_flags & SC_COMP_TCP) && sc->sc_comp != NULL) { - struct ip *ip; - int type; - - mp = m; - ip = (struct ip *) (cp + PPP_HDRLEN); - if (mp->m_len <= PPP_HDRLEN) { - mp = mp->m_next; - if (mp == NULL) - break; - ip = mtod(mp, struct ip *); - } - /* this code assumes the IP/TCP header is in one non-shared mbuf */ - if (ip->ip_p == IPPROTO_TCP) { - type = sl_compress_tcp(mp, ip, sc->sc_comp, - !(sc->sc_flags & SC_NO_TCP_CCID)); - switch (type) { - case TYPE_UNCOMPRESSED_TCP: - protocol = PPP_VJC_UNCOMP; - break; - case TYPE_COMPRESSED_TCP: - protocol = PPP_VJC_COMP; - cp = mtod(m, u_char *); - cp[0] = address; /* header has moved */ - cp[1] = control; - cp[2] = 0; - break; - } - cp[3] = protocol; /* update protocol in PPP header */ - } - } -#endif /* VJC */ - break; - -#ifdef PPP_COMPRESS - case PPP_CCP: - ppp_ccp(sc, m, 0); - break; -#endif /* PPP_COMPRESS */ - } - -#ifdef PPP_COMPRESS - if (protocol != PPP_LCP && protocol != PPP_CCP - && sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) { - struct mbuf *mcomp = NULL; - int slen; - - slen = 0; - for (mp = m; mp != NULL; mp = mp->m_next) - slen += mp->m_len; - (*sc->sc_xcomp->compress) - (sc->sc_xc_state, &mcomp, m, slen, sc->sc_if.if_mtu + PPP_HDRLEN); - if (mcomp != NULL) { - if (sc->sc_flags & SC_CCP_UP) { - /* Send the compressed packet instead of the original. */ - m_freem(m); - m = mcomp; - cp = mtod(m, u_char *); - protocol = cp[3]; - } else { - /* Can't transmit compressed packets until CCP is up. */ - m_freem(mcomp); - } - } - } -#endif /* PPP_COMPRESS */ - - /* - * Compress the address/control and protocol, if possible. - */ - if (sc->sc_flags & SC_COMP_AC && address == PPP_ALLSTATIONS && - control == PPP_UI && protocol != PPP_ALLSTATIONS && - protocol != PPP_LCP) { - /* can compress address/control */ - m->m_data += 2; - m->m_len -= 2; - } - if (sc->sc_flags & SC_COMP_PROT && protocol < 0xFF) { - /* can compress protocol */ - if (mtod(m, u_char *) == cp) { - cp[2] = cp[1]; /* move address/control up */ - cp[1] = cp[0]; - } - ++m->m_data; - --m->m_len; - } - - return m; -} - -#ifdef PPP_COMPRESS -/* - * Handle a CCP packet. `rcvd' is 1 if the packet was received, - * 0 if it is about to be transmitted. - */ -static void -ppp_ccp(struct ppp_softc *sc, struct mbuf *m, int rcvd) -{ - u_char *dp, *ep; - struct mbuf *mp; - int slen; - - /* - * Get a pointer to the data after the PPP header. - */ - if (m->m_len <= PPP_HDRLEN) { - mp = m->m_next; - if (mp == NULL) - return; - dp = (mp != NULL)? mtod(mp, u_char *): NULL; - } else { - mp = m; - dp = mtod(mp, u_char *) + PPP_HDRLEN; - } - - ep = mtod(mp, u_char *) + mp->m_len; - if (dp + CCP_HDRLEN > ep) - return; - slen = CCP_LENGTH(dp); - if (dp + slen > ep) { - if (sc->sc_flags & SC_DEBUG) - kprintf("if_ppp/ccp: not enough data in mbuf (%p+%x > %p+%x)\n", - dp, slen, mtod(mp, u_char *), mp->m_len); - return; - } - - switch (CCP_CODE(dp)) { - case CCP_CONFREQ: - case CCP_TERMREQ: - case CCP_TERMACK: - /* CCP must be going down - disable compression */ - if (sc->sc_flags & SC_CCP_UP) { - crit_enter(); - sc->sc_flags &= ~(SC_CCP_UP | SC_COMP_RUN | SC_DECOMP_RUN); - crit_exit(); - } - break; - - case CCP_CONFACK: - if (sc->sc_flags & SC_CCP_OPEN && !(sc->sc_flags & SC_CCP_UP) - && slen >= CCP_HDRLEN + CCP_OPT_MINLEN - && slen >= CCP_OPT_LENGTH(dp + CCP_HDRLEN) + CCP_HDRLEN) { - if (!rcvd) { - /* we're agreeing to send compressed packets. */ - if (sc->sc_xc_state != NULL - && (*sc->sc_xcomp->comp_init) - (sc->sc_xc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN, - sc->sc_if.if_dunit, 0, sc->sc_flags & SC_DEBUG)) { - crit_enter(); - sc->sc_flags |= SC_COMP_RUN; - crit_exit(); - } - } else { - /* peer is agreeing to send compressed packets. */ - if (sc->sc_rc_state != NULL - && (*sc->sc_rcomp->decomp_init) - (sc->sc_rc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN, - sc->sc_if.if_dunit, 0, sc->sc_mru, - sc->sc_flags & SC_DEBUG)) { - crit_enter(); - sc->sc_flags |= SC_DECOMP_RUN; - sc->sc_flags &= ~(SC_DC_ERROR | SC_DC_FERROR); - crit_exit(); - } - } - } - break; - - case CCP_RESETACK: - if (sc->sc_flags & SC_CCP_UP) { - if (!rcvd) { - if (sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) - (*sc->sc_xcomp->comp_reset)(sc->sc_xc_state); - } else { - if (sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)) { - (*sc->sc_rcomp->decomp_reset)(sc->sc_rc_state); - crit_enter(); - sc->sc_flags &= ~SC_DC_ERROR; - crit_exit(); - } - } - } - break; - } -} - -/* - * CCP is down; free (de)compressor state if necessary. - */ -static void -ppp_ccp_closed(struct ppp_softc *sc) -{ - if (sc->sc_xc_state) { - (*sc->sc_xcomp->comp_free)(sc->sc_xc_state); - sc->sc_xc_state = NULL; - } - if (sc->sc_rc_state) { - (*sc->sc_rcomp->decomp_free)(sc->sc_rc_state); - sc->sc_rc_state = NULL; - } -} -#endif /* PPP_COMPRESS */ - -/* - * PPP packet input routine. - * The caller has checked and removed the FCS and has inserted - * the address/control bytes and the protocol high byte if they - * were omitted. - */ -void -ppppktin(struct ppp_softc *sc, struct mbuf *m, int lost) -{ - crit_enter(); - - if (lost) - m->m_flags |= M_ERRMARK; - IF_ENQUEUE(&sc->sc_rawq, m); - schednetisr(NETISR_PPP); - - crit_exit(); -} - -/* - * Process a received PPP packet, doing decompression as necessary. - * Should be called at splsoftnet. - */ -#define COMPTYPE(proto) ((proto) == PPP_VJC_COMP? TYPE_COMPRESSED_TCP: \ - TYPE_UNCOMPRESSED_TCP) - -static void -ppp_inproc(struct ppp_softc *sc, struct mbuf *m) -{ - struct ifnet *ifp = &sc->sc_if; - int isr; - int ilen = 0, proto, rv; - u_char *cp, adrs, ctrl; - struct mbuf *mp, *dmp = NULL; -#ifdef VJC - int xlen; - u_char *iphdr; - u_int hlen; -#endif - - ASSERT_IFNET_SERIALIZED_ALL(ifp); - - sc->sc_stats.ppp_ipackets++; - - if (sc->sc_flags & SC_LOG_INPKT) { - ilen = 0; - for (mp = m; mp != NULL; mp = mp->m_next) - ilen += mp->m_len; - kprintf("%s: got %d bytes\n", ifp->if_xname, ilen); - pppdumpm(m); - } - - cp = mtod(m, u_char *); - adrs = PPP_ADDRESS(cp); - ctrl = PPP_CONTROL(cp); - proto = PPP_PROTOCOL(cp); - - if (m->m_flags & M_ERRMARK) { - m->m_flags &= ~M_ERRMARK; - crit_enter(); - sc->sc_flags |= SC_VJ_RESET; - crit_exit(); - } - -#ifdef PPP_COMPRESS - /* - * Decompress this packet if necessary, update the receiver's - * dictionary, or take appropriate action on a CCP packet. - */ - if (proto == PPP_COMP && sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN) - && !(sc->sc_flags & SC_DC_ERROR) && !(sc->sc_flags & SC_DC_FERROR)) { - /* decompress this packet */ - rv = (*sc->sc_rcomp->decompress)(sc->sc_rc_state, m, &dmp); - if (rv == DECOMP_OK) { - m_freem(m); - if (dmp == NULL) { - /* no error, but no decompressed packet produced */ - return; - } - m = dmp; - cp = mtod(m, u_char *); - proto = PPP_PROTOCOL(cp); - - } else { - /* - * An error has occurred in decompression. - * Pass the compressed packet up to pppd, which may take - * CCP down or issue a Reset-Req. - */ - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: decompress failed %d\n", ifp->if_xname, rv); - crit_enter(); - sc->sc_flags |= SC_VJ_RESET; - if (rv == DECOMP_ERROR) - sc->sc_flags |= SC_DC_ERROR; - else - sc->sc_flags |= SC_DC_FERROR; - crit_exit(); - } - - } else { - if (sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)) { - (*sc->sc_rcomp->incomp)(sc->sc_rc_state, m); - } - if (proto == PPP_CCP) { - ppp_ccp(sc, m, 1); - } - } -#endif - - ilen = 0; - for (mp = m; mp != NULL; mp = mp->m_next) - ilen += mp->m_len; - -#ifdef VJC - if (sc->sc_flags & SC_VJ_RESET) { - /* - * If we've missed a packet, we must toss subsequent compressed - * packets which don't have an explicit connection ID. - */ - if (sc->sc_comp) - sl_uncompress_tcp(NULL, 0, TYPE_ERROR, sc->sc_comp); - crit_enter(); - sc->sc_flags &= ~SC_VJ_RESET; - crit_exit(); - } - - /* - * See if we have a VJ-compressed packet to uncompress. - */ - if (proto == PPP_VJC_COMP) { - if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == NULL) - goto bad; - - xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN, - ilen - PPP_HDRLEN, TYPE_COMPRESSED_TCP, - sc->sc_comp, &iphdr, &hlen); - - if (xlen <= 0) { - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: VJ uncompress failed on type comp\n", - ifp->if_xname); - goto bad; - } - - /* Copy the PPP and IP headers into a new mbuf. */ - MGETHDR(mp, M_NOWAIT, MT_DATA); - if (mp == NULL) - goto bad; - mp->m_len = 0; - mp->m_next = NULL; - if (hlen + PPP_HDRLEN > MHLEN) { - MCLGET(mp, M_NOWAIT); - if (M_TRAILINGSPACE(mp) < hlen + PPP_HDRLEN) { - m_freem(mp); - goto bad; /* lose if big headers and no clusters */ - } - } - cp = mtod(mp, u_char *); - cp[0] = adrs; - cp[1] = ctrl; - cp[2] = 0; - cp[3] = PPP_IP; - proto = PPP_IP; - bcopy(iphdr, cp + PPP_HDRLEN, hlen); - mp->m_len = hlen + PPP_HDRLEN; - - /* - * Trim the PPP and VJ headers off the old mbuf - * and stick the new and old mbufs together. - */ - m->m_data += PPP_HDRLEN + xlen; - m->m_len -= PPP_HDRLEN + xlen; - if (m->m_len <= M_TRAILINGSPACE(mp)) { - bcopy(mtod(m, u_char *), mtod(mp, u_char *) + mp->m_len, m->m_len); - mp->m_len += m->m_len; - mp->m_next = m_free(m); - } else { - mp->m_next = m; - } - m = mp; - ilen += hlen - xlen; - - } else if (proto == PPP_VJC_UNCOMP) { - if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == NULL) - goto bad; - - xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN, - ilen - PPP_HDRLEN, TYPE_UNCOMPRESSED_TCP, - sc->sc_comp, &iphdr, &hlen); - - if (xlen < 0) { - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: VJ uncompress failed on type uncomp\n", - ifp->if_xname); - goto bad; - } - - proto = PPP_IP; - cp[3] = PPP_IP; - } -#endif /* VJC */ - - /* - * If the packet will fit in a header mbuf, don't waste a - * whole cluster on it. - */ - if (ilen <= MHLEN && M_IS_CLUSTER(m)) { - MGETHDR(mp, M_NOWAIT, MT_DATA); - if (mp != NULL) { - m_copydata(m, 0, ilen, mtod(mp, caddr_t)); - m_freem(m); - m = mp; - m->m_len = ilen; - } - } - m->m_pkthdr.len = ilen; - m->m_pkthdr.rcvif = ifp; - - if ((proto & 0x8000) == 0) { -#ifdef PPP_FILTER - /* - * See whether we want to pass this packet, and - * if it counts as link activity. - */ - adrs = *mtod(m, u_char *); /* save address field */ - *mtod(m, u_char *) = 0; /* indicate inbound */ - if (sc->sc_pass_filt.bf_insns != NULL - && bpf_filter(sc->sc_pass_filt.bf_insns, (u_char *) m, - ilen, 0) == 0) { - /* drop this packet */ - m_freem(m); - return; - } - if (sc->sc_active_filt.bf_insns == NULL - || bpf_filter(sc->sc_active_filt.bf_insns, (u_char *) m, ilen, 0)) - sc->sc_last_recv = time_uptime; - - *mtod(m, u_char *) = adrs; -#else - /* - * Record the time that we received this packet. - */ - sc->sc_last_recv = time_uptime; -#endif /* PPP_FILTER */ - } - - BPF_MTAP(&sc->sc_if, m); - - isr = -1; - switch (proto) { -#ifdef INET - case PPP_IP: - /* - * IP packet - take off the ppp header and pass it up to IP. - */ - if ((ifp->if_flags & IFF_UP) == 0 - || sc->sc_npmode[NP_IP] != NPMODE_PASS) { - /* interface is down - drop the packet. */ - m_freem(m); - return; - } - m->m_pkthdr.len -= PPP_HDRLEN; - m->m_data += PPP_HDRLEN; - m->m_len -= PPP_HDRLEN; -#ifdef notyet - if (ipflow_fastforward(m)) - return; -#endif - isr = NETISR_IP; - break; -#endif - - default: - /* - * Some other protocol - place on input queue for read(). - */ - break; - } - - /* - * If we found a netproto just pass it to the proto. Otherwise queue - * the packet to the tty (e.g. pppd). Note that sc_ctlp() must be - * called EXACTLY once per packet queued. - */ - if (isr == -1) { - struct ifqueue *inq = &sc->sc_inq; - - if (IF_QFULL(inq)) { - IF_DROP(inq); - rv = 0; - } else { - IF_ENQUEUE(inq, m); - sc->sc_ctlp(sc); - rv = 1; - } - } else { - rv = (netisr_queue(isr, m) == 0); - m = NULL; - } - if (!rv) { - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: input queue full\n", ifp->if_xname); - IFNET_STAT_INC(ifp, iqdrops, 1); - goto bad; - } - - IFNET_STAT_INC(ifp, ipackets, 1); - IFNET_STAT_INC(ifp, ibytes, ilen); - getmicrotime(&ifp->if_lastchange); - - return; - - bad: - if (m != NULL) - m_freem(m); - IFNET_STAT_INC(&sc->sc_if, ierrors, 1); - sc->sc_stats.ppp_ierrors++; -} - -#define MAX_DUMP_BYTES 128 - -static void -pppdumpm(struct mbuf *m0) -{ - char buf[3*MAX_DUMP_BYTES+4]; - char *bp = buf; - struct mbuf *m; - - for (m = m0; m; m = m->m_next) { - int l = m->m_len; - u_char *rptr = (u_char *)m->m_data; - - while (l--) { - if (bp > buf + sizeof(buf) - 4) - goto done; - *bp++ = hex2ascii(*rptr >> 4); - *bp++ = hex2ascii(*rptr++ & 0xf); - } - - if (m->m_next) { - if (bp > buf + sizeof(buf) - 3) - goto done; - *bp++ = '|'; - } else - *bp++ = ' '; - } -done: - if (m) - *bp++ = '>'; - *bp = 0; - kprintf("%s\n", buf); -} - -/* - * a wrapper to transmit a packet from if_start since ALTQ uses - * if_start to send a packet. - */ -static void -ppp_ifstart(struct ifnet *ifp, struct ifaltq_subque *ifsq __unused) -{ - struct ppp_softc *sc; - - sc = ifp->if_softc; - (*sc->sc_start)(sc); -} - -MODULE_VERSION(if_ppp, 1); diff --git a/sys/net/ppp/if_ppp.h b/sys/net/ppp/if_ppp.h deleted file mode 100644 index 6a4e620648..0000000000 --- a/sys/net/ppp/if_ppp.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * if_ppp.h - Point-to-Point Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $FreeBSD: src/sys/net/if_ppp.h,v 1.14 1999/08/28 00:48:20 peter Exp $ - * $DragonFly: src/sys/net/ppp/if_ppp.h,v 1.3 2003/08/07 21:17:30 dillon Exp $ - */ - -#ifndef _IF_PPP_H_ -#define _IF_PPP_H_ - -/* XXX this used to be self-contained. */ -#include -#include -#include - -/* - * Packet sizes - */ -#define PPP_MTU 1500 /* Default MTU (size of Info field) */ -#define PPP_MAXMRU 65000 /* Largest MRU we allow */ -#define PPP_MAXMTU 16384 /* Largest MTU we allow */ - -/* - * 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_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 initiated */ -#define SC_DECOMP_RUN 0x00002000 /* decompressor has been initiated */ -#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 */ -#define PPPIOCSPASS _IOW('t', 71, struct bpf_program) /* set pass filter */ -#define PPPIOCSACTIVE _IOW('t', 70, struct bpf_program) /* set active filt */ - -/* 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 - -#endif /* _IF_PPP_H_ */ diff --git a/sys/net/ppp/if_pppvar.h b/sys/net/ppp/if_pppvar.h deleted file mode 100644 index 9b62943698..0000000000 --- a/sys/net/ppp/if_pppvar.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * if_pppvar.h - private structures and declarations for PPP. - * - * Copyright (c) 1994 The Australian National University. - * 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. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * 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. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $FreeBSD: src/sys/net/if_pppvar.h,v 1.15 2000/01/29 16:56:23 peter Exp $ - * $DragonFly: src/sys/net/ppp/if_pppvar.h,v 1.6 2006/07/28 02:17:40 dillon Exp $ - */ - -/* - * Supported network protocols. These values are used for - * indexing sc_npmode. - */ -#define NP_IP 0 /* Internet Protocol */ -#define NUM_NP 1 /* Number of NPs. */ - -/* - * Structure describing each ppp unit. - */ -struct ppp_softc { - struct ifnet sc_if; /* network-visible interface */ -/*hi*/ u_int sc_flags; /* control/status bits; see if_ppp.h */ - struct callout sc_timeout; /* Used for scheduling timeouts */ - void *sc_devp; /* pointer to device-dep structure */ - void (*sc_start) (struct ppp_softc *); /* start output proc */ - void (*sc_ctlp) (struct ppp_softc *); /* rcvd control pkt */ - void (*sc_relinq) (struct ppp_softc *); /* relinquish ifunit */ - void (*sc_setmtu) (struct ppp_softc *); /* set mtu */ - short sc_mru; /* max receive unit */ - struct thread *sc_xfer; /* used in transferring unit */ -/*hi*/ struct ifqueue sc_rawq; /* received packets */ -/*net*/ struct ifqueue sc_inq; /* queue of input packets for daemon */ -/*net*/ struct ifqueue sc_fastq; /* interactive output packet q */ - struct mbuf *sc_npqueue; /* output packets not to be sent yet */ - struct mbuf **sc_npqtail; /* ptr to last next ptr in npqueue */ - struct pppstat sc_stats; /* count of bytes/pkts sent/rcvd */ - enum NPmode sc_npmode[NUM_NP]; /* what to do with each NP */ - struct compressor *sc_xcomp; /* transmit compressor */ - void *sc_xc_state; /* transmit compressor state */ - struct compressor *sc_rcomp; /* receive decompressor */ - void *sc_rc_state; /* receive decompressor state */ - time_t sc_last_sent; /* time (secs) last NP pkt sent */ - time_t sc_last_recv; /* time (secs) last NP pkt rcvd */ -#ifdef PPP_FILTER - struct bpf_program sc_pass_filt; /* filter for packets to pass */ - struct bpf_program sc_active_filt; /* filter for "non-idle" packets */ -#endif /* PPP_FILTER */ -#ifdef VJC - struct slcompress *sc_comp; /* vjc control buffer */ -#endif - - /* Device-dependent part for async lines. */ - ext_accm sc_asyncmap; /* async control character map */ - u_long sc_rasyncmap; /* receive async control char map */ - struct mbuf *sc_outm; /* mbuf chain currently being output */ - struct mbuf *sc_m; /* pointer to input mbuf chain */ - struct mbuf *sc_mc; /* pointer to current input mbuf */ - char *sc_mp; /* ptr to next char in input mbuf */ - short sc_ilen; /* length of input packet so far */ - u_short sc_fcs; /* FCS so far (input) */ - u_short sc_outfcs; /* FCS so far for output packet */ - u_char sc_rawin[16]; /* chars as received */ - int sc_rawin_count; /* # in sc_rawin */ -}; - -extern struct ppp_softc ppp_softc[]; - -struct ppp_softc *pppalloc (struct thread *td); -void pppdealloc (struct ppp_softc *sc); -int pppioctl (struct ppp_softc *sc, u_long cmd, caddr_t data, - int flag, struct ucred *cred); -int pppoutput (struct ifnet *ifp, struct mbuf *m0, - struct sockaddr *dst, struct rtentry *rtp); -void ppp_restart (struct ppp_softc *sc); -void ppppktin (struct ppp_softc *sc, struct mbuf *m, int lost); -struct mbuf *ppp_dequeue (struct ppp_softc *sc); diff --git a/sys/net/ppp_layer/Makefile b/sys/net/ppp_layer/Makefile deleted file mode 100644 index 6f6358c712..0000000000 --- a/sys/net/ppp_layer/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -# $FreeBSD: src/sys/modules/if_ppp/Makefile,v 1.21 1999/11/28 18:52:51 bde Exp $ - -.PATH: ${.CURDIR}/../ppp ${.CURDIR}/.. -KMOD= if_ppp -SRCS= if_ppp.c ppp_tty.c slcompress.c \ - use_ppp.h opt_inet.h opt_ppp.h - -NPPP?= 4 -PPP_BSDCOMP?= 1 # 0/1 -PPP_DEFLATE?= 1 # 0/1 -PPP_FILTER?= 1 # 0/1 - requires bpf to be configured in kernel -PPP_INET?= 1 # 0/1 - requires INET to be configured in kernel - -.if ${PPP_BSDCOMP} > 0 -SRCS+= bsd_comp.c -.endif -.if ${PPP_DEFLATE} > 0 -SRCS+= ppp_deflate.c zlib.c -.endif - -use_ppp.h: - echo "#define NPPP ${NPPP}" > ${.TARGET} - -opt_inet.h: - touch opt_inet.h -.if ${PPP_INET} > 0 - echo "#define INET 1" > ${.TARGET} -.endif - -opt_ppp.h: - touch ${.TARGET} -.if ${PPP_BSDCOMP} > 0 - echo "#define PPP_BSDCOMP ${PPP_BSDCOMP}" > ${.TARGET} -.endif -.if ${PPP_DEFLATE} > 0 - echo "#define PPP_DEFLATE ${PPP_DEFLATE}" >> ${.TARGET} -.endif -.if ${PPP_FILTER} > 0 - echo "#define PPP_FILTER ${PPP_FILTER}" >> ${.TARGET} -.endif - -.include diff --git a/sys/net/ppp_layer/ppp_comp.h b/sys/net/ppp_layer/ppp_comp.h deleted file mode 100644 index 67803035d0..0000000000 --- a/sys/net/ppp_layer/ppp_comp.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * ppp_comp.h - Definitions for doing PPP packet compression. - * - * Copyright (c) 1994 The Australian National University. - * 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. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * 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. - * - * $FreeBSD: src/sys/net/ppp_comp.h,v 1.8 1999/08/28 00:48:25 peter Exp $ - * $DragonFly: src/sys/net/ppp_layer/ppp_comp.h,v 1.3 2003/08/26 20:49:48 rob 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 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 */ diff --git a/sys/net/ppp_layer/ppp_deflate.c b/sys/net/ppp_layer/ppp_deflate.c deleted file mode 100644 index ab47de65b6..0000000000 --- a/sys/net/ppp_layer/ppp_deflate.c +++ /dev/null @@ -1,654 +0,0 @@ -/* $FreeBSD: src/sys/net/ppp_deflate.c,v 1.12.2.1 2002/04/14 21:41:48 luigi Exp $ */ - -/* - * 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 mbufs on BSD-derived systems. - * - * Copyright (c) 1994 The Australian National University. - * 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. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * 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. - */ - -#include -#include -#include -#include -#include "ppp_defs.h" -#include - -#define PACKETPTR struct mbuf * -#include "ppp_comp.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); -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, struct mbuf **mret, - struct mbuf *mp, int slen, int maxolen); -static void z_incomp (void *state, struct mbuf *dmsg); -static int z_decompress (void *state, struct mbuf *cmp, - struct mbuf **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 if_ppp.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 */ -}; - -/* - * Space allocation and freeing routines for use by zlib routines. - */ -static void * -z_alloc(void *notused, u_int items, u_int size) -{ - void *ptr; - - ptr = kmalloc(items * size, M_DEVBUF, M_WAITOK); - return ptr; -} - -static void -z_free(void *notused, void *ptr) -{ - kfree(ptr, M_DEVBUF); -} - -/* - * Allocate space for a compressor. - */ -static void * -z_comp_alloc(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]); - if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE) - return NULL; - - state = kmalloc(sizeof(struct deflate_state), M_DEVBUF, M_WAITOK); - - state->strm.next_in = NULL; - state->strm.zalloc = z_alloc; - state->strm.zfree = z_free; - if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL, - -w_size, 8, Z_DEFAULT_STRATEGY) != Z_OK) { - kfree(state, M_DEVBUF); - return NULL; - } - - state->w_size = w_size; - bzero(&state->stats, sizeof(state->stats)); - return (void *) state; -} - -static void -z_comp_free(void *arg) -{ - struct deflate_state *state = (struct deflate_state *) arg; - - deflateEnd(&state->strm); - kfree(state, M_DEVBUF); -} - -static int -z_comp_init(void *arg, u_char *options, int opt_len, int unit, int hdrlen, - int 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(void *arg) -{ - struct deflate_state *state = (struct deflate_state *) arg; - - state->seqno = 0; - deflateReset(&state->strm); -} - -/* - * Parameters: - * mret: compressed packet (out) - * mp: uncompressed packet (in) - */ -static int -z_compress(void *arg, struct mbuf **mret, struct mbuf *mp, int orig_len, - int maxolen) -{ - struct deflate_state *state = (struct deflate_state *) arg; - u_char *rptr, *wptr; - int proto, olen, wspace, r, flush; - struct mbuf *m; - - /* - * Check that the protocol is in the range we handle. - */ - rptr = mtod(mp, u_char *); - proto = PPP_PROTOCOL(rptr); - if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) { - *mret = NULL; - return orig_len; - } - - /* Allocate one mbuf initially. */ - if (maxolen > orig_len) - maxolen = orig_len; - MGET(m, M_NOWAIT, MT_DATA); - *mret = m; - if (m != NULL) { - m->m_len = 0; - if (maxolen + state->hdrlen > MLEN) - MCLGET(m, M_NOWAIT); - wspace = M_TRAILINGSPACE(m); - if (state->hdrlen + PPP_HDRLEN + 2 < wspace) { - m->m_data += state->hdrlen; - wspace -= state->hdrlen; - } - wptr = mtod(m, u_char *); - - /* - * 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; - wptr = NULL; - wspace = 0; - } - ++state->seqno; - - rptr += (proto > 0xff)? 2: 3; /* skip 1st proto byte if 0 */ - state->strm.next_in = rptr; - state->strm.avail_in = mtod(mp, u_char *) + mp->m_len - rptr; - mp = mp->m_next; - flush = (mp == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH; - olen = 0; - for (;;) { - r = deflate(&state->strm, flush); - if (r != Z_OK) { - kprintf("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 = mtod(mp, u_char *); - state->strm.avail_in = mp->m_len; - mp = mp->m_next; - if (mp == NULL) - flush = Z_PACKET_FLUSH; - } - if (state->strm.avail_out == 0) { - if (m != NULL) { - m->m_len = wspace; - olen += wspace; - MGET(m->m_next, M_NOWAIT, MT_DATA); - m = m->m_next; - if (m != NULL) { - m->m_len = 0; - if (maxolen - olen > MLEN) - MCLGET(m, M_NOWAIT); - state->strm.next_out = mtod(m, u_char *); - state->strm.avail_out = wspace = M_TRAILINGSPACE(m); - } - } - if (m == NULL) { - state->strm.next_out = NULL; - state->strm.avail_out = 1000000; - } - } - } - if (m != NULL) - olen += (m->m_len = wspace - state->strm.avail_out); - - /* - * See if we managed to reduce the size of the packet. - */ - if (m != NULL && olen < orig_len) { - state->stats.comp_bytes += olen; - state->stats.comp_packets++; - } else { - if (*mret != NULL) { - m_freem(*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(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->inc_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(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]); - if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE) - return NULL; - - state = kmalloc(sizeof(struct deflate_state), M_DEVBUF, M_WAITOK); - - state->strm.next_out = NULL; - state->strm.zalloc = z_alloc; - state->strm.zfree = z_free; - if (inflateInit2(&state->strm, -w_size) != Z_OK) { - kfree(state, M_DEVBUF); - return NULL; - } - - state->w_size = w_size; - bzero(&state->stats, sizeof(state->stats)); - return (void *) state; -} - -static void -z_decomp_free(void *arg) -{ - struct deflate_state *state = (struct deflate_state *) arg; - - inflateEnd(&state->strm); - kfree(state, M_DEVBUF); -} - -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[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(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, struct mbuf *mi, struct mbuf **mop) -{ - struct deflate_state *state = (struct deflate_state *) arg; - struct mbuf *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 = mtod(mi, u_char *); - rlen = mi->m_len; - for (i = 0; i < PPP_HDRLEN + DEFLATE_OVHD; ++i) { - while (rlen <= 0) { - mi = mi->m_next; - if (mi == NULL) - return DECOMP_ERROR; - rptr = mtod(mi, u_char *); - rlen = mi->m_len; - } - hdr[i] = *rptr++; - --rlen; - } - - /* Check the sequence number. */ - seq = (hdr[PPP_HDRLEN] << 8) + hdr[PPP_HDRLEN+1]; - if (seq != state->seqno) { - if (state->debug) - kprintf("z_decompress%d: bad seq # %d, expected %d\n", - state->unit, seq, state->seqno); - return DECOMP_ERROR; - } - ++state->seqno; - - /* Allocate an output mbuf. */ - MGETHDR(mo, M_NOWAIT, MT_DATA); - if (mo == NULL) - return DECOMP_ERROR; - mo_head = mo; - mo->m_len = 0; - mo->m_next = NULL; - MCLGET(mo, M_NOWAIT); - ospace = M_TRAILINGSPACE(mo); - if (state->hdrlen + PPP_HDRLEN < ospace) { - mo->m_data += state->hdrlen; - ospace -= state->hdrlen; - } - - /* - * Fill in the first part of the PPP header. The protocol field - * comes from the decompressed data. - */ - wptr = mtod(mo, u_char *); - 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 = rlen; - mi = mi->m_next; - flush = (mi == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH; - rlen += PPP_HDRLEN + DEFLATE_OVHD; - state->strm.next_out = wptr + 3; - state->strm.avail_out = 1; - decode_proto = 1; - olen = PPP_HDRLEN; - - /* - * 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 - kprintf("z_decompress%d: inflate returned %d (%s)\n", - state->unit, r, (state->strm.msg? state->strm.msg: "")); - m_freem(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 = mtod(mi, u_char *); - state->strm.avail_in = mi->m_len; - rlen += mi->m_len; - mi = mi->m_next; - 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; - --olen; - } - decode_proto = 0; - } else { - mo->m_len = ospace; - olen += ospace; - MGET(mo->m_next, M_NOWAIT, MT_DATA); - mo = mo->m_next; - if (mo == NULL) { - m_freem(mo_head); - return DECOMP_ERROR; - } - MCLGET(mo, M_NOWAIT); - state->strm.next_out = mtod(mo, u_char *); - state->strm.avail_out = ospace = M_TRAILINGSPACE(mo); - } - } - } - if (decode_proto) { - m_freem(mo_head); - return DECOMP_ERROR; - } - olen += (mo->m_len = ospace - state->strm.avail_out); -#if DEFLATE_DEBUG - if (state->debug && olen > state->mru + PPP_HDRLEN) - kprintf("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(void *arg, struct mbuf *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 = mtod(mi, u_char *); - proto = PPP_PROTOCOL(rptr); - if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) - return; - - ++state->seqno; - - /* - * Iterate through the mbufs, adding the characters in them - * to the decompressor's history. For the first mbuf, we start - * at the either the 1st or 2nd byte of the protocol field, - * depending on whether the protocol value is compressible. - */ - rlen = mi->m_len; - 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 - kprintf("z_incomp%d: inflateIncomp returned %d (%s)\n", - state->unit, r, (state->strm.msg? state->strm.msg: "")); - return; - } - mi = mi->m_next; - if (mi == NULL) - break; - state->strm.next_in = mtod(mi, u_char *); - state->strm.avail_in = mi->m_len; - rlen += mi->m_len; - } - - /* - * Update stats. - */ - state->stats.inc_bytes += rlen; - state->stats.inc_packets++; - state->stats.unc_bytes += rlen; - state->stats.unc_packets++; -} - -#endif /* DO_DEFLATE */ diff --git a/sys/net/ppp_layer/ppp_tty.c b/sys/net/ppp_layer/ppp_tty.c deleted file mode 100644 index 9ae185562c..0000000000 --- a/sys/net/ppp_layer/ppp_tty.c +++ /dev/null @@ -1,1144 +0,0 @@ -/* - * (MPSAFE) - * - * ppp_tty.c - Point-to-Point Protocol (PPP) driver for asynchronous - * tty devices. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * Drew D. Perkins - * Carnegie Mellon University - * 4910 Forbes Ave. - * Pittsburgh, PA 15213 - * (412) 268-8576 - * ddp@andrew.cmu.edu - * - * Based on: - * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89 - * - * Copyright (c) 1987 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. - * - * Serial Line interface - * - * Rick Adams - * Center for Seismic Studies - * 1300 N 17th Street, Suite 1450 - * Arlington, Virginia 22209 - * (703)276-7900 - * rick@seismo.ARPA - * seismo!rick - * - * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris). - * Converted to 4.3BSD Beta by Chris Torek. - * Other changes made at Berkeley, based in part on code by Kirk Smith. - * - * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com) - * Added VJ tcp header compression; more unified ioctls - * - * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au). - * Cleaned up a lot of the mbuf-related code to fix bugs that - * caused system crashes and packet corruption. Changed pppstart - * so that it doesn't just give up with a "collision" if the whole - * packet doesn't fit in the output ring buffer. - * - * Added priority queueing for interactive IP packets, following - * the model of if_sl.c, plus hooks for bpf. - * Paul Mackerras (paulus@cs.anu.edu.au). - */ - -/* $FreeBSD: src/sys/net/ppp_tty.c,v 1.43.2.1 2002/02/13 00:43:11 dillon Exp $ */ - -#include "opt_ppp.h" /* XXX for ppp_defs.h */ - -#define VJC /* XXX for ppp_defs.h */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef PPP_FILTER -#include -#endif -#include -#include - -static int pppopen (cdev_t dev, struct tty *tp); -static int pppclose (struct tty *tp, int flag); -static int pppread (struct tty *tp, struct uio *uio, int flag); -static int pppwrite (struct tty *tp, struct uio *uio, int flag); -static int ppptioctl (struct tty *tp, u_long cmd, caddr_t data, - int flag, struct ucred *); -static int pppinput (int c, struct tty *tp); -static int pppstart (struct tty *tp); - -static u_short pppfcs (u_short fcs, u_char *cp, int len); -static void pppasyncstart (struct ppp_softc *); -static void pppasyncctlp (struct ppp_softc *); -static void pppasyncrelinq (struct ppp_softc *); -static void pppasyncsetmtu (struct ppp_softc *); -static void ppp_timeout (void *); -static void pppgetm (struct ppp_softc *sc); -static void ppplogchar (struct ppp_softc *, int); - -/* XXX called from if_ppp.c - layering violation */ -void pppasyncattach (void *); - -/* - * Some useful mbuf macros not in mbuf.h. - */ -#define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT) - -#define M_DATASTART(m) \ - (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \ - (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat) - -#define M_DATASIZE(m) \ - (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \ - (m)->m_flags & M_PKTHDR ? MHLEN: MLEN) - -/* - * Does c need to be escaped? - */ -#define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F))) - -/* - * Procedures for using an async tty interface for PPP. - */ - -/* This is a FreeBSD-2.X kernel. */ -#define CCOUNT(q) ((q)->c_cc) -#define PPP_LOWAT 100 /* Process more output when < LOWAT on queue */ -#define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */ - -/* - * Define the PPP line discipline. - */ - -static struct linesw pppdisc = { - pppopen, pppclose, pppread, pppwrite, - ppptioctl, pppinput, pppstart, ttymodem, - PPP_FLAG -}; - -void -pppasyncattach(void *dummy) -{ - /* register line discipline */ - linesw[PPPDISC] = pppdisc; -} - -/* - * Line specific open routine for async tty devices. - * Attach the given tty to the first available ppp unit. - * Called from device open routine or ttioctl() at >= splsofttty() - */ -/* ARGSUSED */ -static int -pppopen(cdev_t dev, struct tty *tp) -{ - struct thread *td = curthread; /* XXX */ - struct ppp_softc *sc; - int error; - - if ((error = priv_check(td, PRIV_ROOT)) != 0) - return (error); - - crit_enter(); - lwkt_gettoken(&tty_token); - - if (tp->t_line == PPPDISC) { - sc = (struct ppp_softc *) tp->t_slsc; - if (sc != NULL && sc->sc_devp == (void *) tp) { - lwkt_reltoken(&tty_token); - crit_exit(); - return (0); - } - } - - if ((sc = pppalloc(td)) == NULL) { - lwkt_reltoken(&tty_token); - crit_exit(); - return ENXIO; - } - - if (sc->sc_relinq) - (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */ - - sc->sc_ilen = 0; - sc->sc_m = NULL; - bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap)); - sc->sc_asyncmap[0] = 0xffffffff; - sc->sc_asyncmap[3] = 0x60000000; - sc->sc_rasyncmap = 0; - sc->sc_devp = (void *) tp; - sc->sc_start = pppasyncstart; - sc->sc_ctlp = pppasyncctlp; - sc->sc_relinq = pppasyncrelinq; - sc->sc_setmtu = pppasyncsetmtu; - sc->sc_outm = NULL; - pppgetm(sc); - sc->sc_if.if_flags |= IFF_RUNNING; - getmicrotime(&sc->sc_if.if_lastchange); - sc->sc_if.if_baudrate = tp->t_ospeed; - - tp->t_slsc = (caddr_t) sc; - ttyflush(tp, FREAD | FWRITE); - - /* - * Pre-allocate cblocks to the "just right" amount. The 1 byte t_canq - * allocation helps avoid the need for select and/or FIONREAD. - * We also pass 1 byte tokens through t_canq... - */ - clist_alloc_cblocks(&tp->t_canq, 1, 1); - clist_alloc_cblocks(&tp->t_outq, sc->sc_if.if_mtu + PPP_HIWAT, - sc->sc_if.if_mtu + PPP_HIWAT); - clist_alloc_cblocks(&tp->t_rawq, 0, 0); - - lwkt_reltoken(&tty_token); - crit_exit(); - - return (0); -} - -/* - * Line specific close routine, called from device close routine - * and from ttioctl at >= splsofttty(). - * Detach the tty from the ppp unit. - * Mimics part of ttyclose(). - */ -static int -pppclose(struct tty *tp, int flag) -{ - struct ppp_softc *sc; - - crit_enter(); - lwkt_gettoken(&tty_token); - ttyflush(tp, FREAD | FWRITE); - clist_free_cblocks(&tp->t_canq); - clist_free_cblocks(&tp->t_outq); - tp->t_line = 0; - sc = (struct ppp_softc *) tp->t_slsc; - if (sc != NULL) { - tp->t_slsc = NULL; - if (tp == (struct tty *) sc->sc_devp) { - pppasyncrelinq(sc); - pppdealloc(sc); - } - } - lwkt_reltoken(&tty_token); - crit_exit(); - return 0; -} - -/* - * Relinquish the interface unit to another device. - */ -static void -pppasyncrelinq(struct ppp_softc *sc) -{ - crit_enter(); - lwkt_gettoken(&tty_token); - - if (sc->sc_outm) { - m_freem(sc->sc_outm); - sc->sc_outm = NULL; - } - if (sc->sc_m) { - m_freem(sc->sc_m); - sc->sc_m = NULL; - } - if (sc->sc_flags & SC_TIMEOUT) { - callout_stop(&sc->sc_timeout); - sc->sc_flags &= ~SC_TIMEOUT; - } - - lwkt_reltoken(&tty_token); - crit_exit(); -} - -/* - * This gets called from the upper layer to notify a mtu change - */ -static void -pppasyncsetmtu(struct ppp_softc *sc) -{ - struct tty *tp = (struct tty *) sc->sc_devp; - - crit_enter(); - lwkt_gettoken(&tty_token); - if (tp != NULL) - clist_alloc_cblocks(&tp->t_outq, sc->sc_if.if_mtu + PPP_HIWAT, - sc->sc_if.if_mtu + PPP_HIWAT); - lwkt_reltoken(&tty_token); - crit_exit(); -} - -/* - * Line specific (tty) read routine. - * called at zero spl from the device driver in the response to user-level - * reads on the tty file descriptor (ie: pppd). - */ -static int -pppread(struct tty *tp, struct uio *uio, int flag) -{ - struct ppp_softc *sc = (struct ppp_softc *)tp->t_slsc; - struct mbuf *m, *m0; - int error = 0; - - if (sc == NULL) - return 0; - /* - * Loop waiting for input, checking that nothing disasterous - * happens in the meantime. - */ - crit_enter(); - lwkt_gettoken(&tty_token); - for (;;) { - if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC) { - lwkt_reltoken(&tty_token); - crit_exit(); - return 0; - } - if (sc->sc_inq.ifq_head != NULL) - break; - if ((tp->t_state & TS_CONNECTED) == 0) { - lwkt_reltoken(&tty_token); - crit_exit(); - return 0; /* end of file */ - } - if (tp->t_state & TS_ASYNC || flag & IO_NDELAY) { - lwkt_reltoken(&tty_token); - crit_exit(); - return (EWOULDBLOCK); - } - error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), PCATCH, "pppin", 0); - if (error) { - lwkt_reltoken(&tty_token); - crit_exit(); - return error; - } - } - - /* Pull place-holder byte out of canonical queue */ - clist_getc(&tp->t_canq); - - /* Get the packet from the input queue */ - IF_DEQUEUE(&sc->sc_inq, m0); - lwkt_reltoken(&tty_token); - crit_exit(); - - for (m = m0; m && uio->uio_resid; m = m->m_next) - if ((error = uiomove(mtod(m, u_char *), m->m_len, uio)) != 0) - break; - m_freem(m0); - return (error); -} - -/* - * Line specific (tty) write routine. - * called at zero spl from the device driver in the response to user-level - * writes on the tty file descriptor (ie: pppd). - */ -static int -pppwrite(struct tty *tp, struct uio *uio, int flag) -{ - struct ppp_softc *sc = (struct ppp_softc *)tp->t_slsc; - struct mbuf *m, *m0, **mp; - struct sockaddr dst; - int len, error; - - lwkt_gettoken(&tty_token); - if ((tp->t_state & TS_CONNECTED) == 0) { - lwkt_reltoken(&tty_token); - return 0; /* wrote 0 bytes */ - } - if (tp->t_line != PPPDISC) { - lwkt_reltoken(&tty_token); - return (EINVAL); - } - if (sc == NULL || tp != (struct tty *) sc->sc_devp) { - lwkt_reltoken(&tty_token); - return EIO; - } - if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HDRLEN || - uio->uio_resid < PPP_HDRLEN) { - lwkt_reltoken(&tty_token); - return (EMSGSIZE); - } - - crit_enter(); - for (mp = &m0; uio->uio_resid; mp = &m->m_next) { - if (mp == &m0) { - MGETHDR(m, M_WAITOK, MT_DATA); - m->m_pkthdr.len = uio->uio_resid - PPP_HDRLEN; - m->m_pkthdr.rcvif = NULL; - } else { - MGET(m, M_WAITOK, MT_DATA); - } - if ((*mp = m) == NULL) { - m_freem(m0); - crit_exit(); - lwkt_reltoken(&tty_token); - return (ENOBUFS); - } - m->m_len = 0; - if (uio->uio_resid >= MCLBYTES / 2) - MCLGET(m, M_NOWAIT); - len = M_TRAILINGSPACE(m); - if (len > uio->uio_resid) - len = uio->uio_resid; - if ((error = uiomove(mtod(m, u_char *), len, uio)) != 0) { - m_freem(m0); - crit_exit(); - lwkt_reltoken(&tty_token); - return (error); - } - m->m_len = len; - } - dst.sa_family = AF_UNSPEC; - bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN); - m0->m_data += PPP_HDRLEN; - m0->m_len -= PPP_HDRLEN; - - /* call the upper layer to "transmit" it... */ - error = pppoutput(&sc->sc_if, m0, &dst, NULL); - crit_exit(); - lwkt_reltoken(&tty_token); - return (error); -} - -/* - * Line specific (tty) ioctl routine. - * This discipline requires that tty device drivers call - * the line specific l_ioctl routine from their ioctl routines. - */ -/* ARGSUSED */ -static int -ppptioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct ucred *cr) -{ - struct ppp_softc *sc = (struct ppp_softc *) tp->t_slsc; - int error; - - lwkt_gettoken(&tty_token); - if (sc == NULL || tp != (struct tty *) sc->sc_devp) { - lwkt_reltoken(&tty_token); - return (ENOIOCTL); - } - - error = 0; - switch (cmd) { - case PPPIOCSASYNCMAP: - if ((error = priv_check_cred(cr, PRIV_ROOT, 0)) != 0) - break; - sc->sc_asyncmap[0] = *(u_int *)data; - break; - - case PPPIOCGASYNCMAP: - *(u_int *)data = sc->sc_asyncmap[0]; - break; - - case PPPIOCSRASYNCMAP: - if ((error = priv_check_cred(cr, PRIV_ROOT, 0)) != 0) - break; - sc->sc_rasyncmap = *(u_int *)data; - break; - - case PPPIOCGRASYNCMAP: - *(u_int *)data = sc->sc_rasyncmap; - break; - - case PPPIOCSXASYNCMAP: - if ((error = priv_check_cred(cr, PRIV_ROOT, 0)) != 0) - break; - crit_enter(); - bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap)); - sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */ - sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */ - sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */ - crit_exit(); - break; - - case PPPIOCGXASYNCMAP: - bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap)); - break; - - default: - error = pppioctl(sc, cmd, data, flag, cr); - if (error == 0 && cmd == PPPIOCSMRU) - pppgetm(sc); - } - - lwkt_reltoken(&tty_token); - return error; -} - -/* - * 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 -}; - -/* - * Calculate a new FCS given the current FCS and the new data. - */ -static u_short -pppfcs(u_short fcs, u_char *cp, int len) -{ - while (len--) - fcs = PPP_FCS(fcs, *cp++); - return (fcs); -} - -/* - * This gets called at splsoftnet from if_ppp.c at various times - * when there is data ready to be sent. - */ -static void -pppasyncstart(struct ppp_softc *sc) -{ - struct tty *tp = (struct tty *) sc->sc_devp; - struct mbuf *m; - int len; - u_char *start, *stop, *cp; - int n, ndone, done, idle; - - idle = 0; - lwkt_gettoken(&tty_token); - /* XXX assumes atomic access to *tp although we're not at spltty(). */ - while (CCOUNT(&tp->t_outq) < PPP_HIWAT) { - /* - * See if we have an existing packet partly sent. - * If not, get a new packet and start sending it. - */ - m = sc->sc_outm; - if (m == NULL) { - /* - * Get another packet to be sent. - */ - m = ppp_dequeue(sc); - if (m == NULL) { - idle = 1; - break; - } - - /* - * The extra PPP_FLAG will start up a new packet, and thus - * will flush any accumulated garbage. We do this whenever - * the line may have been idle for some time. - */ - /* XXX as above. */ - if (CCOUNT(&tp->t_outq) == 0) { - ++sc->sc_stats.ppp_obytes; - clist_putc(PPP_FLAG, &tp->t_outq); - } - - /* Calculate the FCS for the first mbuf's worth. */ - sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len); - getmicrotime(&sc->sc_if.if_lastchange); - } - - for (;;) { - start = mtod(m, u_char *); - len = m->m_len; - stop = start + len; - while (len > 0) { - /* - * Find out how many bytes in the string we can - * handle without doing something special. - */ - for (cp = start; cp < stop; cp++) - if (ESCAPE_P(*cp)) - break; - n = cp - start; - if (n) { - /* NetBSD (0.9 or later), 4.3-Reno or similar. */ - ndone = n - b_to_q(start, n, &tp->t_outq); - len -= ndone; - start += ndone; - sc->sc_stats.ppp_obytes += ndone; - - if (ndone < n) - break; /* packet doesn't fit */ - } - /* - * If there are characters left in the mbuf, - * the first one must be special. - * Put it out in a different form. - */ - if (len) { - crit_enter(); - if (clist_putc(PPP_ESCAPE, &tp->t_outq)) { - crit_exit(); - break; - } - if (clist_putc(*start ^ PPP_TRANS, &tp->t_outq)) { - clist_unputc(&tp->t_outq); - crit_exit(); - break; - } - crit_exit(); - sc->sc_stats.ppp_obytes += 2; - start++; - len--; - } - } - - /* - * If we didn't empty this mbuf, remember where we're up to. - * If we emptied the last mbuf, try to add the FCS and closing - * flag, and if we can't, leave sc_outm pointing to m, but with - * m->m_len == 0, to remind us to output the FCS and flag later. - */ - done = len == 0; - if (done && m->m_next == NULL) { - u_char *p, *q; - int c; - u_char endseq[8]; - - /* - * We may have to escape the bytes in the FCS. - */ - p = endseq; - c = ~sc->sc_outfcs & 0xFF; - if (ESCAPE_P(c)) { - *p++ = PPP_ESCAPE; - *p++ = c ^ PPP_TRANS; - } else - *p++ = c; - c = (~sc->sc_outfcs >> 8) & 0xFF; - if (ESCAPE_P(c)) { - *p++ = PPP_ESCAPE; - *p++ = c ^ PPP_TRANS; - } else - *p++ = c; - *p++ = PPP_FLAG; - - /* - * Try to output the FCS and flag. If the bytes - * don't all fit, back out. - */ - crit_enter(); - for (q = endseq; q < p; ++q) - if (clist_putc(*q, &tp->t_outq)) { - done = 0; - for (; q > endseq; --q) - clist_unputc(&tp->t_outq); - break; - } - crit_exit(); - if (done) - sc->sc_stats.ppp_obytes += q - endseq; - } - - if (!done) { - /* remember where we got to */ - m->m_data = start; - m->m_len = len; - break; - } - - /* Finished with this mbuf; free it and move on. */ - m = m_free(m); - if (m == NULL) { - /* Finished a packet */ - break; - } - sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len); - } - - /* - * If m == NULL, we have finished a packet. - * If m != NULL, we've either done as much work this time - * as we need to, or else we've filled up the output queue. - */ - sc->sc_outm = m; - if (m) - break; - } - - /* Call pppstart to start output again if necessary. */ - crit_enter(); - pppstart(tp); - - /* - * This timeout is needed for operation on a pseudo-tty, - * because the pty code doesn't call pppstart after it has - * drained the t_outq. - */ - if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) { - callout_reset(&sc->sc_timeout, 1, ppp_timeout, sc); - sc->sc_flags |= SC_TIMEOUT; - } - - crit_exit(); - lwkt_reltoken(&tty_token); -} - -/* - * This gets called when a received packet is placed on - * the inq, at splsoftnet. The pppd daemon is to be woken up to do a read(). - */ -static void -pppasyncctlp(struct ppp_softc *sc) -{ - struct tty *tp; - - /* Put a placeholder byte in canq for ttselect()/ttnread(). */ - crit_enter(); - lwkt_gettoken(&tty_token); - tp = (struct tty *) sc->sc_devp; - clist_putc(0, &tp->t_canq); - ttwakeup(tp); - lwkt_reltoken(&tty_token); - crit_exit(); -} - -/* - * Start output on async tty interface. If the transmit queue - * has drained sufficiently, arrange for pppasyncstart to be - * called later at splsoftnet. - * Called at spltty or higher. - */ -static int -pppstart(struct tty *tp) -{ - struct ppp_softc *sc = (struct ppp_softc *) tp->t_slsc; - - lwkt_gettoken(&tty_token); - /* - * Call output process whether or not there is any output. - * We are being called in lieu of ttstart and must do what it would. - */ - if (tp->t_oproc != NULL) - (*tp->t_oproc)(tp); - - /* - * If ALTQ is enabled, don't invoke NETISR_PPP. - * pppintr() could loop without doing anything useful - * under rate-limiting. - */ - if (ifq_is_enabled(&sc->sc_if.if_snd)) { - lwkt_reltoken(&tty_token); - return 0; - } - - /* - * If the transmit queue has drained and the tty has not hung up - * or been disconnected from the ppp unit, then tell if_ppp.c that - * we need more output. - */ - if (CCOUNT(&tp->t_outq) < PPP_LOWAT - && !((tp->t_state & TS_CONNECTED) == 0) - && sc != NULL && tp == (struct tty *) sc->sc_devp) { - ppp_restart(sc); - } - - lwkt_reltoken(&tty_token); - return 0; -} - -/* - * Timeout routine - try to start some more output. - */ -static void -ppp_timeout(void *x) -{ - struct ppp_softc *sc = (struct ppp_softc *) x; - struct tty *tp = (struct tty *) sc->sc_devp; - - crit_enter(); - lwkt_gettoken(&tty_token); - sc->sc_flags &= ~SC_TIMEOUT; - pppstart(tp); - lwkt_reltoken(&tty_token); - crit_exit(); -} - -/* - * Allocate enough mbuf to handle current MRU. - */ -static void -pppgetm(struct ppp_softc *sc) -{ - struct mbuf *m, **mp; - int len; - - mp = &sc->sc_m; - for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){ - if ((m = *mp) == NULL) { - MGETHDR(m, M_NOWAIT, MT_DATA); - if (m == NULL) - break; - *mp = m; - MCLGET(m, M_NOWAIT); - } - len -= M_DATASIZE(m); - mp = &m->m_next; - } -} - -/* - * tty interface receiver interrupt. - */ -static unsigned paritytab[8] = { - 0x96696996, 0x69969669, 0x69969669, 0x96696996, - 0x69969669, 0x96696996, 0x96696996, 0x69969669 -}; - -/* - * Called when character is available from device driver. - * Only guaranteed to be at splsofttty() or spltty() - * This is safe to be called while the upper half's netisr is preempted. - */ -static int -pppinput(int c, struct tty *tp) -{ - struct ppp_softc *sc; - struct mbuf *m; - int ilen; - - lwkt_gettoken(&tty_token); - sc = (struct ppp_softc *) tp->t_slsc; - if (sc == NULL || tp != (struct tty *) sc->sc_devp) { - lwkt_reltoken(&tty_token); - return 0; - } - - ++tk_nin; - ++sc->sc_stats.ppp_ibytes; - - if ((tp->t_state & TS_CONNECTED) == 0) { - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: no carrier\n", sc->sc_if.if_xname); - goto flush; - } - - if (c & TTY_ERRORMASK) { - /* framing error or overrun on this char - abort packet */ - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: line error %x\n", sc->sc_if.if_xname, - c & TTY_ERRORMASK); - goto flush; - } - - c &= TTY_CHARMASK; - - /* - * Handle software flow control of output. - */ - if (tp->t_iflag & IXON) { - if (c == tp->t_cc[VSTOP] && tp->t_cc[VSTOP] != _POSIX_VDISABLE) { - if ((tp->t_state & TS_TTSTOP) == 0) { - tp->t_state |= TS_TTSTOP; - tp->t_stop(tp, 0); - } - lwkt_reltoken(&tty_token); - return 0; - } - if (c == tp->t_cc[VSTART] && tp->t_cc[VSTART] != _POSIX_VDISABLE) { - tp->t_state &= ~TS_TTSTOP; - if (tp->t_oproc != NULL) - (*tp->t_oproc)(tp); - lwkt_reltoken(&tty_token); - return 0; - } - } - - crit_enter(); - if (c & 0x80) - sc->sc_flags |= SC_RCV_B7_1; - else - sc->sc_flags |= SC_RCV_B7_0; - if (paritytab[c >> 5] & (1 << (c & 0x1F))) - sc->sc_flags |= SC_RCV_ODDP; - else - sc->sc_flags |= SC_RCV_EVNP; - crit_exit(); - - if (sc->sc_flags & SC_LOG_RAWIN) - ppplogchar(sc, c); - - if (c == PPP_FLAG) { - ilen = sc->sc_ilen; - sc->sc_ilen = 0; - - if (sc->sc_rawin_count > 0) - ppplogchar(sc, -1); - - /* - * If SC_ESCAPED is set, then we've seen the packet - * abort sequence "}~". - */ - if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED) - || (ilen > 0 && sc->sc_fcs != PPP_GOODFCS)) { - crit_enter(); - sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */ - if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){ - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: bad fcs %x, pkt len %d\n", - sc->sc_if.if_xname, sc->sc_fcs, ilen); - IFNET_STAT_INC(&sc->sc_if, ierrors, 1); - sc->sc_stats.ppp_ierrors++; - } else - sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED); - crit_exit(); - lwkt_reltoken(&tty_token); - return 0; - } - - if (ilen < PPP_HDRLEN + PPP_FCSLEN) { - if (ilen) { - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: too short (%d)\n", sc->sc_if.if_xname, ilen); - crit_enter(); - IFNET_STAT_INC(&sc->sc_if, ierrors, 1); - sc->sc_stats.ppp_ierrors++; - sc->sc_flags |= SC_PKTLOST; - crit_exit(); - } - lwkt_reltoken(&tty_token); - return 0; - } - - /* - * Remove FCS trailer. Somewhat painful... - */ - ilen -= 2; - if (--sc->sc_mc->m_len == 0) { - for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next) - ; - sc->sc_mc = m; - } - sc->sc_mc->m_len--; - - /* excise this mbuf chain */ - m = sc->sc_m; - sc->sc_m = sc->sc_mc->m_next; - sc->sc_mc->m_next = NULL; - - ppppktin(sc, m, sc->sc_flags & SC_PKTLOST); - if (sc->sc_flags & SC_PKTLOST) { - crit_enter(); - sc->sc_flags &= ~SC_PKTLOST; - crit_exit(); - } - - pppgetm(sc); - lwkt_reltoken(&tty_token); - return 0; - } - - if (sc->sc_flags & SC_FLUSH) { - if (sc->sc_flags & SC_LOG_FLUSH) - ppplogchar(sc, c); - lwkt_reltoken(&tty_token); - return 0; - } - - if (c < 0x20 && (sc->sc_rasyncmap & (1 << c))) { - lwkt_reltoken(&tty_token); - return 0; - } - - crit_enter(); - if (sc->sc_flags & SC_ESCAPED) { - sc->sc_flags &= ~SC_ESCAPED; - c ^= PPP_TRANS; - } else if (c == PPP_ESCAPE) { - sc->sc_flags |= SC_ESCAPED; - crit_exit(); - lwkt_reltoken(&tty_token); - return 0; - } - crit_exit(); - - /* - * Initialize buffer on first octet received. - * First octet could be address or protocol (when compressing - * address/control). - * Second octet is control. - * Third octet is first or second (when compressing protocol) - * octet of protocol. - * Fourth octet is second octet of protocol. - */ - if (sc->sc_ilen == 0) { - /* reset the first input mbuf */ - if (sc->sc_m == NULL) { - pppgetm(sc); - if (sc->sc_m == NULL) { - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: no input mbufs!\n", sc->sc_if.if_xname); - goto flush; - } - } - m = sc->sc_m; - m->m_len = 0; - m->m_data = M_DATASTART(sc->sc_m); - sc->sc_mc = m; - sc->sc_mp = mtod(m, char *); - sc->sc_fcs = PPP_INITFCS; - if (c != PPP_ALLSTATIONS) { - if (sc->sc_flags & SC_REJ_COMP_AC) { - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: garbage received: 0x%x (need 0xFF)\n", - sc->sc_if.if_xname, c); - goto flush; - } - *sc->sc_mp++ = PPP_ALLSTATIONS; - *sc->sc_mp++ = PPP_UI; - sc->sc_ilen += 2; - m->m_len += 2; - } - } - if (sc->sc_ilen == 1 && c != PPP_UI) { - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: missing UI (0x3), got 0x%x\n", - sc->sc_if.if_xname, c); - goto flush; - } - if (sc->sc_ilen == 2 && (c & 1) == 1) { - /* a compressed protocol */ - *sc->sc_mp++ = 0; - sc->sc_ilen++; - sc->sc_mc->m_len++; - } - if (sc->sc_ilen == 3 && (c & 1) == 0) { - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: bad protocol %x\n", sc->sc_if.if_xname, - (sc->sc_mp[-1] << 8) + c); - goto flush; - } - - /* packet beyond configured mru? */ - if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) { - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: packet too big\n", sc->sc_if.if_xname); - goto flush; - } - - /* is this mbuf full? */ - m = sc->sc_mc; - if (M_TRAILINGSPACE(m) <= 0) { - if (m->m_next == NULL) { - pppgetm(sc); - if (m->m_next == NULL) { - if (sc->sc_flags & SC_DEBUG) - kprintf("%s: too few input mbufs!\n", sc->sc_if.if_xname); - goto flush; - } - } - sc->sc_mc = m = m->m_next; - m->m_len = 0; - m->m_data = M_DATASTART(m); - sc->sc_mp = mtod(m, char *); - } - - ++m->m_len; - *sc->sc_mp++ = c; - sc->sc_fcs = PPP_FCS(sc->sc_fcs, c); - lwkt_reltoken(&tty_token); - return 0; - - flush: - if (!(sc->sc_flags & SC_FLUSH)) { - crit_enter(); - IFNET_STAT_INC(&sc->sc_if, ierrors, 1); - sc->sc_stats.ppp_ierrors++; - sc->sc_flags |= SC_FLUSH; - crit_exit(); - if (sc->sc_flags & SC_LOG_FLUSH) - ppplogchar(sc, c); - } - lwkt_reltoken(&tty_token); - return 0; -} - -#define MAX_DUMP_BYTES 128 - -static void -ppplogchar(struct ppp_softc *sc, int c) -{ - char *hexstr; - - if (c >= 0) - sc->sc_rawin[sc->sc_rawin_count++] = c; - if (sc->sc_rawin_count >= sizeof(sc->sc_rawin) - || (c < 0 && sc->sc_rawin_count > 0)) { - hexstr = kmalloc(HEX_NCPYLEN(sc->sc_rawin_count), M_TEMP, M_WAITOK | M_ZERO); - kprintf("%s input: %s", sc->sc_if.if_xname, hexncpy(sc->sc_rawin, - sc->sc_rawin_count, hexstr, HEX_NCPYLEN(sc->sc_rawin_count), " ")); - sc->sc_rawin_count = 0; - kfree(hexstr, M_TEMP); - } -} diff --git a/sys/sys/param.h b/sys/sys/param.h index f791521620..87e0a0b3a5 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -162,9 +162,10 @@ * 400910 - routing table is only available on netisr_ncpus * 500000 - 5.0 release * 500100 - 5.1 development + * 500101 - kernel ppp removal */ #undef __DragonFly_version -#define __DragonFly_version 500100 /* propagated to newvers */ +#define __DragonFly_version 500101 /* propagated to newvers */ #include diff --git a/usr.bin/chat/chat.8 b/usr.bin/chat/chat.8 index 7150d1eac4..ec193fadec 100644 --- a/usr.bin/chat/chat.8 +++ b/usr.bin/chat/chat.8 @@ -1,7 +1,7 @@ .\" -*- nroff -*- .\" manual page [] for chat 1.8 .\" $FreeBSD: src/usr.bin/chat/chat.8,v 1.15.2.3 2003/02/24 22:37:41 trhodes Exp $ -.Dd September 27, 1996 +.Dd October 17, 2017 .Dt CHAT 8 .Os .Sh NAME @@ -19,12 +19,6 @@ The .Nm 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 -.Xr ( pppd 8 ) -and the remote's -.Xr pppd 8 -process. .Sh OPTIONS The following options are provided: .Bl -tag -width ".Fl U Ar phone_number" -offset indent @@ -90,9 +84,10 @@ The .Nm 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. +This device is usually the local console at the station running the chat or +the +.Xr ppp 8 +program. .It Fl s Use stderr. All log messages from @@ -287,12 +282,6 @@ The .Dq SAY directive allows the script to send strings to the user at the terminal via standard error. -If -.Nm -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 -.Pa /etc/ppp/connect-errors . .Pp .Dq SAY strings must be enclosed in single or double quotes. diff --git a/usr.bin/crunch/examples/really-big.conf b/usr.bin/crunch/examples/really-big.conf index 57755e22b5..d6015642a4 100644 --- a/usr.bin/crunch/examples/really-big.conf +++ b/usr.bin/crunch/examples/really-big.conf @@ -69,7 +69,7 @@ srcdirs /usr/src/usr.sbin progs ac accton amd arp bad144 catman chown chroot config config.new cron progs dev_mkdb diskpart edquota flcopy gettable grfinfo hilinfo htable inetd -progs iostat iteconfig kvm_mkdb mtree named portmap pppd +progs iostat iteconfig kvm_mkdb mtree named portmap progs pstat pwd_mkdb quot quotaon rarpd rbootd repquota rmt rpc.bootparamd progs rwhod sa spray sysctl syslogd tcpdump progs traceroute trpt update vipw vnconfig ypbind yppoll ypset diff --git a/usr.bin/rfcomm_sppd/rfcomm_sppd.1 b/usr.bin/rfcomm_sppd/rfcomm_sppd.1 index 67f9fb68b5..66157a614f 100644 --- a/usr.bin/rfcomm_sppd/rfcomm_sppd.1 +++ b/usr.bin/rfcomm_sppd/rfcomm_sppd.1 @@ -52,7 +52,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 10, 2007 +.Dd October 17, 2017 .Dt RFCOMM_SPPD 1 .Os .Sh NAME @@ -183,23 +183,11 @@ can be used to communicate with the remote serial port on the server, e.g. with the use of .Pp .Dl cu -l /dev/ttyp1 -.Pp -In order to use -.Nm -to automatically create a secured link for -.Xr pppd 8 , -use -.Dl pty Qo rfcomm_sppd -a 00:01:02:03:04:05 -s DUN -m secure Qc -.Pp -in your -.Xr pppd 8 -configuration file. .Sh SEE ALSO .Xr bluetooth 3 , .Xr bluetooth 4 , .Xr pty 4 , .Xr btconfig 8 , -.Xr pppd 8 , .Xr sdpd 8 .Sh HISTORY The diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 8007bc4c48..4d20c3f9f3 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -77,7 +77,6 @@ SUBDIR= 802_11 \ pflogd \ powerd \ pppctl \ - pppstats \ prefix \ procctl \ pstat \ @@ -146,7 +145,6 @@ SUBDIR= 802_11 \ # Uses lib[re]ssl but can build without it # SUBDIR+=ppp \ - pppd \ tcpdump # from old secure/ diff --git a/usr.sbin/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp.8.m4 index 1a3c96963b..b5ef751c51 100644 --- a/usr.sbin/ppp/ppp.8.m4 +++ b/usr.sbin/ppp/ppp.8.m4 @@ -27,7 +27,7 @@ changecom(,)dnl .\" .\" $FreeBSD: src/usr.sbin/ppp/ppp.8.m4,v 1.301.2.1 2002/09/01 02:12:31 brian Exp $ .\" -.Dd June 20, 2015 +.Dd October 17, 2017 .Dt PPP 8 .Os .Sh NAME @@ -43,16 +43,8 @@ changecom(,)dnl .Sh DESCRIPTION This is a user process .Em PPP -software package. -Normally, -.Em PPP -is implemented as a part of the kernel (e.g., as managed by -.Xr pppd 8 ) -and it's thus somewhat hard to debug and/or modify its behaviour. -However, in this implementation -.Em PPP -is done as a user process with the help of the -tunnel device driver (tun). +software package with the help of the tunnel device driver +.Xr ( tun 4 ). .Pp The .Fl nat @@ -2661,7 +2653,7 @@ program. Note: There is a problem negotiating .Ar deflate capabilities with -.Xr pppd 8 +.Nm pppd - a .Em PPP implementation available under many operating systems. @@ -2694,7 +2686,7 @@ Default: Disabled and Denied. This is a variance of the .Ar deflate option, allowing negotiation with the -.Xr pppd 8 +.Nm pppd program. Refer to the .Ar deflate @@ -2829,7 +2821,7 @@ acts as the authenticatee with both protocols the protocols are used alternately in response to challenges. .Pp Note: If only LANMan is enabled, -.Xr pppd 8 +.Nm pppd (version 2.3.5) misbehaves when acting as authenticatee. It provides both the NT and the LANMan answers, but also suggests that only the NT answer @@ -5839,7 +5831,6 @@ ifdef({LOCALRAD},{},{.Xr libradius 3 , .Xr named 8 , .Xr ping 8 , .Xr pppctl 8 , -.Xr pppd 8 , .Xr pppoe 8 , .Xr route 8 , .Xr sshd 8 , diff --git a/usr.sbin/pppd/Makefile b/usr.sbin/pppd/Makefile deleted file mode 100644 index e97171c59f..0000000000 --- a/usr.sbin/pppd/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -# $FreeBSD: src/usr.sbin/pppd/Makefile,v 1.19.2.2 2001/08/19 03:32:43 kris Exp $ - -CFLAGS+= -DHAVE_PATHS_H - -PROG= pppd -SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c ccp.c \ - demand.c auth.c options.c sys-bsd.c -MAN= pppd.8 -BINMODE=4550 -BINOWN= root -BINGRP= dialer -WARNS?= 2 - -LDADD= -lcrypt -lutil -lmd -DPADD= ${LIBCRYPT} ${LIBUTIL} ${LIBMD} - -# Callback Control Protocol -CFLAGS+=-DCBCP_SUPPORT -SRCS+= cbcp.c - -# Filter support -CFLAGS+=-DPPP_FILTER -I${.CURDIR}/../../contrib/libpcap -CFLAGS+=-include ${.CURDIR}/../../lib/libpcap/config.h -LDADD+= -lpcap -DPADD+= ${LIBPCAP} - -# MS-CHAP support. Requires the DES library. -.if !defined(NO_CRYPT) -CFLAGS+= -DCHAPMS -SRCS+= chap_ms.c -LDADD+= -lprivate_crypto -DPADD+= ${LIBRECRYPTO} -LDFLAGS+= ${PRIVATELIB_LDFLAGS} -CFLAGS+= -I${.CURDIR}/../../crypto/libressl/include -.endif - -# XXX sys/md5.h shim errata for bootstrap REMOVE_OPENSSL_FILES -CFLAGS+= -I${_SHLIBDIRPREFIX}/usr/include/priv - -.include diff --git a/usr.sbin/pppd/RELNOTES b/usr.sbin/pppd/RELNOTES deleted file mode 100644 index 12d9c7f223..0000000000 --- a/usr.sbin/pppd/RELNOTES +++ /dev/null @@ -1,724 +0,0 @@ -This is the README file for ppp-2.3, a package which implements the -Point-to-Point Protocol (PPP) to provide Internet connections over -serial lines. - - -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 the protocols layered above IP, such as TCP and UDP. -The Linux port of this package also has support for IPX. - -This software 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 -SunOS 4.x, Solaris 2.x, System V Release 4, and OSF/1, and as a -line discipline under Ultrix, NextStep, NetBSD, FreeBSD, and 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. - - -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: - - Digital Unix (OSF/1) README.osf - Linux README.linux - NetBSD, FreeBSD README.bsd - NeXTStep README.next - Solaris 2 README.sol2 - SunOS 4.x README.sunos4 - System V Release 4 README.svr4 - Ultrix 4.x README.ultrix - -Unfortunately, AIX 4 is no longer supported, since I don't have a -maintainer for the AIX 4 port. If you want to volunteer, contact me. -The Ultrix port is untested, as I no longer have access to an Ultrix -box. - -In each case you start by running the ./configure script. This works -out which operating system you are using and creates symbolic links to -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. - -The procedures for installing the kernel code vary from system to -system. On some systems, the kernel code can be loaded into a running -kernel using a `modload' facility. On others, the kernel image has to -be recompiled and the system rebooted. See the README.* files for -details. - -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.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. - - -Patents. -******** - -The BSD-Compress algorithm used for packet compression is the same as -that used in the Unix "compress" command. It is apparently covered by -U.S. patents 4,814,746 (owned by IBM) and 4,558,302 (owned by Unisys), -and corresponding patents in various other countries (but not -Australia). If this is of concern, you can build the package without -including BSD-Compress. To do this, edit net/ppp-comp.h to change the -definition of DO_BSD_COMPRESS to 0. The bsd-comp.c files are then no -longer needed, so the references to bsd-comp.o may optionally be -removed from the Makefiles. - - -Contacts. -********* - -The comp.protocols.ppp newsgroup is a useful place to get help if you -have trouble getting your ppp connections to work. Please do not send -me questions of the form "please help me get connected to my ISP" - -I'm sorry, but I simply do not have the time to answer all the -questions like this that I get. - -If you find bugs in this package, please report them to the maintainer -for the port for the operating system you are using: - -Digital Unix (OSF/1) Farrell Woods -Linux Al Longyear -NetBSD Matthew Green -NeXTStep Steve Perkins -Solaris 2 Paul Mackerras -SunOS 4.x Paul Mackerras -System V Release 4 Matthias Apitz -Ultrix 4.x Paul Mackerras (for want of anybody better :-) - - -Copyrights: -*********** - -All of the code can be freely used and redistributed. - - -Distribution: -************* - -The primary site for releases of this software is: - - ftp://cs.anu.edu.au/pub/software/ppp/ - -------------------------- -This is the README file for ppp-2.2, a package which implements the -Point-to-Point Protocol (PPP) to provide Internet connections over -serial lines. - - -Introduction. -************* - -The Point-to-Point Protocol (PPP) provides a standard way to transmit -datagrams over a serial link, as well as a standard way for the -machines at either end of the link (the `peers') to negotiate various -optional characteristics of the link. Using PPP, a serial link can be -used to transmit Internet Protocol (IP) datagrams, allowing TCP/IP -connections between the peers. PPP is defined in several RFC (Request -For Comments) documents, in particular RFCs 1661, 1662, 1332 and 1334. -Other RFCs describe standard ways to transmit datagrams from other -network protocols (e.g., DECnet, OSI, Appletalk), but this package -only supports IP. - -This software 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 -SunOS 4.x, AIX 4.1 and OSF/1, and as a line discipline under Ultrix, -NextStep, NetBSD, FreeBSD, and 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. - - -What is new in ppp-2.2. -*********************** - -* More systems are now supported: - - AIX 4, thanks to Charlie Wick, - OSF/1 on DEC Alpha, thanks to Steve Tate (srt@zaphod.csci.unt.edu), - NextStep 3.2 and 3.3, thanks to Philip-Andrew Prindeville - (philipp@res.enst.fr) and Steve Perkins (perkins@cps.msu.edu), - Solaris 2, - -in addition to NetBSD 1.0, SunOS 4.x, Ultrix 4.x, FreeBSD 2.0, and -Linux. - -* Packet compression has been implemented. This version implements -CCP (Compression Control Protocol) and the BSD-Compress compression -scheme according to the current draft RFCs. This means that incoming -and outgoing packets can be compressed with the LZW scheme (same as -the `compress' command) using a code size of up to 15 bits. - -* Some bug fixes to the LCP protocol code. In particular, pppd now -correctly replies with a Configure-NAK (instead of a Configure-Reject) -if the peer asks for CHAP and pppd is willing to do PAP but not CHAP. - -* The ip-up and ip-down scripts are now run with the real user ID set -to root, and with an empty environment. Clearing the environment -fixes a security hole. - -* The kernel code on NetBSD, FreeBSD, NextStep and Ultrix has been -restructured to make it easier to implement PPP over devices other -than asynchronous tty ports (for example, synchronous serial ports). - -* pppd now looks at the list of interfaces in the system to determine -what the netmask should be. In most cases, this should eliminate the -need to use the `netmask' option. - -* There is a new `papcrypt' option to pppd, which specifies that -secrets in /etc/ppp/pap-secrets used for authenticating the peer are -encrypted, so pppd always encrypts the peer's password before -comparing it with the secret from /etc/ppp/pap-secrets. This gives -better security. - - -Patents. -******** - -The BSD-Compress algorithm used for packet compression is the same as -that used in the Unix "compress" command. It is apparently covered by -U.S. patents 4,814,746 (owned by IBM) and 4,558,302 (owned by Unisys), -and corresponding patents in various other countries (but not -Australia). If this is of concern, you can build the package without -including BSD-Compress. To do this, edit net/ppp-comp.h to change the -definition of DO_BSD_COMPRESS to 0. The bsd-comp.c files are then no -longer needed, so the references to bsd-comp.o may optionally be -removed from the Makefiles. - - -Contacts. -********* - -Bugs in the the SunOS, NetBSD and Ultrix ports and bugs in pppd, chat -or pppstats should be reported to: - - paulus@cs.anu.edu.au - Paul Mackerras - Dept. of Computer Science - Australian National University - Canberra ACT 0200 - AUSTRALIA - -Bugs in other ports should be reported to the maintainer for that port -(see the appropriate README.* file) or to the above. Unfortunately, -Charlie Wick is not in a position to provide support for the AIX 4 -port, so if you find bugs in it, send them to me. - -Thanks to: - - Brad Parker (brad@fcr.com) - Greg Christy (gmc@quotron.com) - Drew D. Perkins (ddp@andrew.cmu.edu) - Rick Adams (rick@seismo.ARPA) - Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris). - - -Copyrights: - -Most of the code can be freely used and redistributed. The STREAMS -code for SunOS 4.x, OSF/1 and AIX 4 is under a more restrictive -copyright: - - This code is Copyright (C) 1989, 1990 By Brad K. Clements, - All Rights Reserved. - - You may use this code for your personal use, to provide a non-profit - service to others, or to use as a test platform for a commercial - implementation. - - You may NOT use this code in a commercial product, nor to provide a - commercial service, nor may you sell this code without express - written permission of the author. - - Otherwise, Enjoy! - -This copyright applies to (parts of) the following files: - - sunos/ppp_async.c - sunos/ppp_if.c - aix4/ppp_async.c - aix4/ppp_if.c - net/ppp_str.h - pppd/sys-str.c - pppd/sys-osf.c - pppd/sys-aix4.c -------------------------- - pppd-2.1.1 release notes - Paul Mackerras 27 May 1994 - -This file details the new and changed features in pppd since version 1.3. -Briefly: - - the protocol code has been updated to conform with - RFCs 1548, 1549, 1332 and 1334 - - security has been improved - - functionality has been improved in various ways. - - -NEW FEATURES - -* The option negotiation automaton has been updated to RFC1548. LCP -now rejects the Quality Protocol option, since LQR is not implemented -yet. IPCP now uses the IP-Address option, and falls back to the old -IP-Addresses option if the IP-Address option is rejected. IPCP also -uses the new form of the VJ-Compression option. - -RFC1548 defines the "passive" option to mean that the automaton -outputs configure-request packets initially, but does not close down -if no answer is received. A valid configure-request received will -restart the negotiation. The "silent" option has been added with the -old meaning of "passive", i.e. the automaton will not output -configure-requests until it receives a valid one from the peer. - -* More systems are supported: in addition to SunOS 4.x and BSD/Net-2 -derived systems, Ultrix and Linux are supported, thanks to Robert -Olsson, Per Sundstrom, Michael Callahan and Al Longyear. - -* Options can be taken from files as well as the command line. pppd -reads options from the files /etc/ppp/options and ~/.ppprc before -looking at the command line, and /etc/ppp/options. after -interpreting the options on the command line. 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 quotes ("). -Backslash (\) quotes the following character. A hash (#) starts a -comment, which continues until the end of the line. In addition, the -`file' option causes pppd to read options from a file. pppd will -report and error and exit if ~/.ppprc or the file given as the -argument to the `file' option cannot be read by the user who invoked -pppd. - -* On those systems, such as NetBSD, where the serial line speed is -stored in the termios structure in bits per second (i.e. B9600 == -9600), it is possible to set any speed. - -* If desired, pppd will output LCP echo-request frames periodically -while the link is up, and take the link down if no replies are -received to a user-configurable number of echo-requests. This can be -used to detect that the serial connection has been broken on those -systems which don't have hardware modem control lines. - -AUTHENTICATION - -Previous versions of pppd have provided no control over which IP -addresses the peer can use. Thus it is possible for the peer to -impersonate another host on the local network, leading to various -security holes. In addition, the authentication mechanisms were quite -weak: if the peer refused to agree to authenticate, pppd would print a -warning message but still allow the link to come up. The CHAP -implementation also appeared to be quite broken (has anybody actually -used it?). - -This new version of pppd addresses these problems. My aim has been to -provide 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. In part this is provided by the /etc/ppp/options file, where the -administrator can place options to require authentication which cannot -be disabled by users. Thus the new pppd can made setuid-root and run -by users. - -The behaviour where pppd refuses to run unless the /etc/ppp/options -file is present and readable by pppd is now the default behaviour. If -you really want pppd to run without the presence of the -/etc/ppp/options file, you will have to include -DREQ_SYSOPTIONS=0 on -the compilation command line. - -The options related to authentication are: - - auth Require authentication from the peer. If neither - +chap or +pap is also given, either CHAP or PAP - authentication will be accepted. - +chap Require CHAP authentication from the peer. - +pap Require PAP authentication from the peer. - -chap Don't agree to authenticate ourselves with the peer - using CHAP. - -pap Don't agree to authenticate ourselves using PAP. - +ua Get username and password for authenticating ourselves - with the peer using PAP from file . - name Use as the local name for authentication. - usehostname Use this machine's hostname as the local name for - authentication. - remotename Use as the name of the peer for authentication. - login If the peer authenticates using PAP, check the - supplied username and password against the system - password database, and make a wtmp entry. - user Use as the username for authenticating ourselves - using PAP. - -The defaults are 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. - -Authentication is based on secrets, which are selected from secrets -files (/etc/ppp/pap-secrets for PAP, /etc/ppp/chap-secrets for CHAP). -Both secrets files have the same format, and both can store secrets -for several combinations of server (authenticating peer) and client -(peer being authenticated). Note that each end can be both a server -and client, and that different protocols can be used in the two -directions if desired. - -A secrets file is parsed into words as for a options file. A secret -is specified by a line containing at least 3 words, in the order -client, server, secret. 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, it is assumed that any IP address -is OK; to disallow all IP addresses, use "-". 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. - -Thus a secrets file contains both secrets for use in authenticating -other hosts, plus secrets which we use for authenticating ourselves to -others. Which secret to use is chosen based on the names of the host -(the `local name') and its peer (the `remote name'). The local name -is set as follows: - - if the `usehostname' option is given, - then the local name is the hostname of this machine - (with the domain appended, if given) - - else if the `name' option is given, - then use the argument of the first `name' option seen - - else if the local IP address is specified with a - host name (e.g. `sirius:') - then use that host name - - else use the hostname of this machine - (with the domain appended, if given) - -When authenticating ourselves using PAP, there is also a `username' -which is the local name by default, but can be set with the `user' -option or the `+ua' option. - -The remote name is set as follows: - - if the `remotename' option is given, - then use the argument of the last `remotename' option seen - - else if the remote IP address is specified with a - host name (e.g. `avago:') - then use that host name - - else the remote name is the null string "". - -Secrets are selected from the PAP secrets file as follows: - -- For authenticating the peer, look for a secret with client == -username specified in the PAP authenticate-request, and server == -local name. - -- For authenticating ourselves to the peer, look for a secret with -client == our username, server == remote name. - -When authenticating the peer with PAP, a secret of "" matches any -password supplied by the peer. 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 the `login' 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. - -Secrets are selected from the CHAP secrets file as follows: - -- For authenticating the peer, look for a secret with client == name -specified in the CHAP-Response message, and server == local name. - -- For authenticating ourselves to the peer, look for a secret with -client == local name, and server == name specified in the -CHAP-Challenge message. - -Authentication must be satisfactorily completed before IPCP (or any -other Network Control Protocol) can be started. If authentication -fails, 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 cannot be sent or received until IPCP is -successfully opened. - -(some examples needed here perhaps) - - -ROUTING - -Setting the addresses on a ppp interface is sufficient to create a -host route to the remote end of the link. 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 `defaultroute' option causes pppd to create such a -default route when IPCP comes up, and delete it when the link is -terminated. - -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 `proxyarp' option causes pppd -to look for a network interface (an interface supporting broadcast and -ARP, which is up and not a point-to-point or loopback interface) on -the same subnet as the remote host. 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. - - -OTHER NEW AND CHANGED OPTIONS - - modem Use modem control lines (not fully implemented - yet) - local Don't use modem control lines - persist Keep reopening connection (not fully - implemented yet) - - lcp-restart Set timeout for LCP retransmissions to - seconds (default 3 seconds) - lcp-max-terminate Set maximum number of LCP terminate-request - transmissions (default 2) - lcp-max-configure Set maximum number of LCP configure-request - transmissions (default 10) - lcp-max-failure Set maximum number of LCP configure-Naks sent - before converting to configure-rejects - (default 10) - - ipcp-restart Set timeout for IPCP retransmissions to - seconds (default 3 seconds) - ipcp-max-terminate Set maximum number of IPCP - terminate-request transmissions (default 2) - ipcp-max-configure Set maximum number of IPCP - configure-request transmissions (default 10) - ipcp-max-failure Set maximum number of IPCP configure-Naks - sent before converting to configure-rejects - (default 10) - - upap-restart Set timeout for PAP retransmissions to - seconds (default 3 seconds) - upap-max-authreq Set maximum number of Authenticate-request - retransmissions (default 10) - - chap-restart Set timeout for CHAP retransmissions to - seconds (default 3 seconds) - chap-max-challenge Set maximum number of CHAP Challenge - retransmissions (default 10) - chap-interval Set the interval between CHAP rechallenges - (default 0, meaning infinity) - -The -ua option no longer exists. - - -SOFTWARE RESTRUCTURING - -Many of the source files for pppd have changed significantly from -ppp-1.3, upon which it is based. In particular: - -- the macros for system-dependent operations in pppd.h have mostly -been removed. Instead these operations are performed by procedures in -sys-bsd.c (for BSD-4.4ish systems like NetBSD, 386BSD, etc.) or -sys-str.c (for SunOS-based systems using STREAMS). (I got sick of -having to recompile everything every time I wanted to change one of -those horrible macros.) - -- most of the system-dependent code in main.c has also been removed to -sys-bsd.c and sys-str.c. - -- the option processing code in main.c has been removed to options.c. - -- the authentication code in main.c has been removed to auth.c, which -also contains substantial amounts of new code. - -- fsm.c has changed significantly, and lcp.c, ipcp.c, and upap.c have -changed somewhat. chap.c has also changed significantly. - - -STILL TO DO - -* sort out appropriate modem control and implement the persist option -properly; add an `answer' option for auto-answering a modem. - -* add an inactivity timeout and demand dialing. - -* implement link quality monitoring. - -* implement other network control protocols. diff --git a/usr.sbin/pppd/auth.c b/usr.sbin/pppd/auth.c deleted file mode 100644 index 8b6979d45c..0000000000 --- a/usr.sbin/pppd/auth.c +++ /dev/null @@ -1,1584 +0,0 @@ -/* - * auth.c - PPP authentication and phase control. - * - * Copyright (c) 1993 The Australian National University. - * 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 Australian National University. 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. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/auth.c,v 1.24.2.2 2002/03/12 08:55:22 maxim Exp $ - */ - -#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 -#include -#include - -#ifdef USE_PAM -#include -#endif - -#ifdef HAS_SHADOW -#include -#ifndef PW_PPP -#define PW_PPP PW_LOGIN -#endif -#endif - -#include "pppd.h" -#include "fsm.h" -#include "lcp.h" -#include "ipcp.h" -#include "upap.h" -#include "chap.h" -#ifdef CBCP_SUPPORT -#include "cbcp.h" -#endif -#include "pathnames.h" - -/* Used for storing a sequence of words. Usually malloced. */ -struct wordlist { - struct wordlist *next; - char word[1]; -}; - -/* Bits in scan_authfile return value */ -#define NONWILD_SERVER 1 -#define NONWILD_CLIENT 2 - -#define ISWILD(word) (word[0] == '*' && word[1] == 0) - -#define FALSE 0 -#define TRUE 1 - -/* 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]; - -/* Set if we have successfully called plogin() */ -static int logged_in; - -/* Set if not wild or blank */ -static int non_wildclient; - -/* Set if we have run the /etc/ppp/auth-up script. */ -static int did_authup; - -/* List of addresses which the peer may use. */ -static struct wordlist *addresses[NUM_PPP]; - -/* 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; - -/* Bits in auth_pending[] */ -#define PAP_WITHPEER 1 -#define PAP_PEER 2 -#define CHAP_WITHPEER 4 -#define CHAP_PEER 8 - -extern char *crypt(const char *, const char *); - -/* 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 plogin(char *, char *, char **, int *); -static void plogout(void); -static int null_login(int); -static int get_pap_passwd(char *); -static int have_pap_secret(void); -static int have_chap_secret(char *, char *, u_int32_t); -static int ip_addr_check(u_int32_t, struct wordlist *); -static int scan_authfile(FILE *, char *, char *, u_int32_t, char *, - struct wordlist **, char *); -static void free_wordlist(struct wordlist *); -static void auth_set_ip_addr(int); -static void auth_script(char *); -static void set_allowed_addrs(int, struct wordlist *); - -/* - * An Open on LCP has requested a change from Dead to Establish phase. - * Do what's necessary to bring the physical layer up. - */ -void -link_required(int unit) -{ -} - -/* - * LCP has terminated the link; go to the Dead phase and take the - * physical layer down. - */ -void -link_terminated(int unit) -{ - extern time_t etime, stime; - extern int minutes; - - if (phase == PHASE_DEAD) - return; - if (logged_in) - plogout(); - phase = PHASE_DEAD; - etime = time(NULL); - minutes = (etime-stime)/60; - syslog(LOG_NOTICE, "Connection terminated, connected for %d minutes\n", - minutes > 1 ? minutes : 1); -} - -/* - * LCP has gone down; it will either die or try to re-establish. - */ -void -link_down(int unit) -{ - int i; - struct protent *protp; - - if (did_authup) { - auth_script(_PATH_AUTHDOWN); - did_authup = 0; - } - 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; - if (phase != PHASE_DEAD) - phase = PHASE_TERMINATE; -} - -/* - * 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]; - int i; - struct protent *protp; - - /* - * Tell higher-level protocols that LCP is up. - */ - 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 && !(go->neg_chap || go->neg_upap)) { - /* - * We wanted the peer to authenticate itself, and it refused: - * 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 (!wo->neg_upap || !null_login(unit)) { - syslog(LOG_WARNING, "peer refused to authenticate"); - lcp_close(unit, "peer refused to authenticate"); - return; - } - } - - phase = PHASE_AUTHENTICATE; - auth = 0; - if (go->neg_chap) { - ChapAuthPeer(unit, our_name, go->chap_mdtype); - auth |= CHAP_PEER; - } else if (go->neg_upap) { - upap_authpeer(unit); - auth |= PAP_PEER; - } - if (ho->neg_chap) { - ChapAuthWithPeer(unit, user, ho->chap_mdtype); - auth |= CHAP_WITHPEER; - } else if (ho->neg_upap) { - if (passwd[0] == 0) { - passwd_from_file = 1; - if (!get_pap_passwd(passwd)) - syslog(LOG_ERR, "No secret found for PAP login"); - } - upap_authwithpeer(unit, user, passwd); - auth |= PAP_WITHPEER; - } - auth_pending[unit] = auth; - - if (!auth) - network_phase(unit); -} - -/* - * Proceed to the network phase. - */ -static void -network_phase(int unit) -{ - int i; - struct protent *protp; - lcp_options *go = &lcp_gotoptions[unit]; - - /* - * If the peer had to authenticate, run the auth-up script now. - */ - if ((go->neg_chap || go->neg_upap) && !did_authup) { - auth_script(_PATH_AUTHUP); - did_authup = 1; - } - -#ifdef CBCP_SUPPORT - /* - * If we negotiated callback, do it now. - */ - if (go->neg_cbcp) { - phase = PHASE_CALLBACK; - (*cbcp_protent.open)(unit); - return; - } -#endif - - phase = PHASE_NETWORK; -#if 0 - if (!demand) - set_filters(&pass_filter, &active_filter); -#endif - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol < 0xC000 && protp->enabled_flag - && protp->open != NULL) { - (*protp->open)(unit); - if (protp->protocol != PPP_CCP) - ++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 - */ - lcp_close(unit, "Authentication failed"); -} - -/* - * The peer has been successfully authenticated using `protocol'. - */ -void -auth_peer_success(int unit, int protocol, char *name, int namelen) -{ - int bit; - - switch (protocol) { - case PPP_CHAP: - bit = CHAP_PEER; - break; - case PPP_PAP: - bit = PAP_PEER; - break; - default: - syslog(LOG_WARNING, "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; - - /* - * If we have overridden addresses based on auth info - * then set that information now before continuing. - */ - auth_set_ip_addr(unit); - - script_setenv("PEERNAME", peer_authname); - - /* - * 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. - * He'll probably take the link down, and there's not much - * we can do except wait for that. - */ -} - -/* - * We have successfully authenticated ourselves with the peer using `protocol'. - */ -void -auth_withpeer_success(int unit, int protocol) -{ - int bit; - - switch (protocol) { - case PPP_CHAP: - bit = CHAP_WITHPEER; - break; - case PPP_PAP: - if (passwd_from_file) - BZERO(passwd, MAXSECRETLEN); - bit = PAP_WITHPEER; - break; - default: - syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x", - protocol); - bit = 0; - } - - /* - * If we have overridden addresses based on auth info - * then set that information now before continuing. - */ - auth_set_ip_addr(unit); - - /* - * 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) -{ - if (num_np_up == 0) { - /* - * At this point we consider that the link has come up successfully. - */ - need_holdoff = 0; - - if (idle_time_limit > 0) - TIMEOUT(check_idle, NULL, idle_time_limit); - - /* - * Set a timeout to close the connection once the maximum - * connect time has expired. - */ - if (maxconnect > 0) - TIMEOUT(connect_time_expired, 0, maxconnect); - - /* - * Detach now, if the updetach option was given. - */ - if (nodetach == -1) - detach(); - } - ++num_np_up; -} - -/* - * np_down - a network protocol has gone down. - */ -void -np_down(int unit, int proto) -{ - if (--num_np_up == 0 && idle_time_limit > 0) { - UNTIMEOUT(check_idle, NULL); - } -} - -/* - * 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"); - } -} - -/* - * 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; - - if (!get_idle_time(0, &idle)) - return; - itime = MIN(idle.xmit_idle, idle.recv_idle); - if (itime >= idle_time_limit) { - /* link is idle: shut it down. */ - syslog(LOG_INFO, "Terminating connection due to lack of activity."); - lcp_close(0, "Link inactive"); - } else { - TIMEOUT(check_idle, NULL, idle_time_limit - itime); - } -} - -/* - * connect_time_expired - log a message and close the connection. - */ -static void -connect_time_expired(void *arg) -{ - syslog(LOG_INFO, "Connect time expired"); - 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; - ipcp_options *ipwo = &ipcp_wantoptions[0]; - u_int32_t remote; - - /* Default our_name to hostname, and user to our_name */ - if (our_name[0] == 0 || usehostname) - strcpy(our_name, hostname); - if (user[0] == 0) - strcpy(user, our_name); - - /* If authentication is required, ask peer for CHAP or PAP. */ - if (auth_required && !wo->neg_chap && !wo->neg_upap) { - wo->neg_chap = 1; - wo->neg_upap = 1; - } - - /* - * Check whether we have appropriate secrets to use - * to authenticate the peer. - */ - can_auth = wo->neg_upap && (uselogin || have_pap_secret()); - if (!can_auth && wo->neg_chap) { - remote = ipwo->accept_remote? 0: ipwo->hisaddr; - can_auth = have_chap_secret(remote_name, our_name, remote); - } - - if (auth_required && !can_auth) { - option_error("peer authentication required but no suitable secret(s) found\n"); - if (remote_name[0] == 0) - option_error("for authenticating any peer to us (%s)\n", our_name); - else - option_error("for authenticating peer %s to us (%s)\n", - remote_name, our_name); - exit(1); - } - - /* - * Check whether the user tried to override certain values - * set by root. - */ - if (!auth_required && auth_req_info.priv > 0) { - if (!default_device && devnam_info.priv == 0) { - option_error("can't override device name when noauth option used"); - exit(1); - } - if ((connector != NULL && connector_info.priv == 0) - || (disconnector != NULL && disconnector_info.priv == 0) - || (welcomer != NULL && welcomer_info.priv == 0)) { - option_error("can't override connect, disconnect or welcome"); - option_error("option values when noauth option used"); - exit(1); - } - } -} - -/* - * 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[0]; - ipcp_options *ipwo = &ipcp_wantoptions[0]; - u_int32_t remote; - - ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); - ao->neg_chap = !refuse_chap - && have_chap_secret(user, remote_name, (u_int32_t)0); - - if (go->neg_upap && !uselogin && !have_pap_secret()) - go->neg_upap = 0; - if (go->neg_chap) { - remote = ipwo->accept_remote? 0: ipwo->hisaddr; - if (!have_chap_secret(remote_name, our_name, remote)) - go->neg_chap = 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 *msglen) -{ - int ret; - char *filename; - FILE *f; - struct wordlist *addrs; - u_int32_t remote; - ipcp_options *ipwo = &ipcp_wantoptions[unit]; - char passwd[256], user[256]; - char secret[MAXWORDLEN]; - static int attempts = 0; - int len; - char *cryptpw; - - /* - * Make copies of apasswd and auser, then null-terminate them. - */ - len = MIN(passwdlen, sizeof(passwd) - 1); - BCOPY(apasswd, passwd, len); - passwd[len] = '\0'; - len = MIN(userlen, sizeof(user) - 1); - BCOPY(auser, user, len); - user[len] = '\0'; - *msg = NULL; - - /* - * Open the file of pap secrets and scan for a suitable secret - * for authenticating this user. - */ - filename = _PATH_UPAPFILE; - addrs = NULL; - ret = UPAP_AUTHACK; - f = fopen(filename, "r"); - if (f == NULL) { - syslog(LOG_ERR, "Can't open PAP password file %s: %m", filename); - ret = UPAP_AUTHNAK; - - } else { - check_access(f, filename); - remote = ipwo->accept_remote? 0: ipwo->hisaddr; - if (scan_authfile(f, user, our_name, remote, - secret, &addrs, filename) < 0) { - warn("no PAP secret found for %s", user); - } else { - if (secret[0] != 0) { - /* password given in pap-secrets - must match */ - cryptpw = crypt(passwd, secret); - - if ((cryptpap || strcmp(passwd, secret) != 0) - && (cryptpw == NULL || strcmp(cryptpw, secret) != 0)) { - ret = UPAP_AUTHNAK; - warn("PAP authentication failure for %s", user); - } - } - } - fclose(f); - } - - if (uselogin && ret == UPAP_AUTHACK) { - ret = plogin(user, passwd, msg, msglen); - if (ret == UPAP_AUTHNAK) { - syslog(LOG_WARNING, "PAP login failure for %s", user); - } - } - - if (ret == UPAP_AUTHNAK) { - if (*msg == NULL) - *msg = "Login incorrect"; - *msglen = strlen(*msg); - /* - * 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) { - syslog(LOG_WARNING, "%d LOGIN FAILURES ON %s, %s", - attempts, devnam, user); - quit(); - } - if (attempts > 3) - sleep((u_int) (attempts - 3) * 5); - if (addrs != NULL) - free_wordlist(addrs); - - } else { - attempts = 0; /* Reset count */ - if (*msg == NULL) - *msg = "Login ok"; - *msglen = strlen(*msg); - set_allowed_addrs(unit, addrs); - } - - BZERO(passwd, sizeof(passwd)); - BZERO(secret, sizeof(secret)); - - return ret; -} - -/* - * Check if an "entry" is in the file "fname" - used by ppplogin. - * Taken from libexec/ftpd/ftpd.c - * Returns: 0 if not found, 1 if found, 2 if file can't be opened for reading. - */ -static int -checkfile(char *fname, char *name) -{ - FILE *fd; - int found = 0; - char *p, line[BUFSIZ]; - - if ((fd = fopen(fname, "r")) != NULL) { - while (fgets(line, sizeof(line), fd) != NULL) - if ((p = strchr(line, '\n')) != NULL) { - *p = '\0'; - if (line[0] == '#') - continue; - if (strcmp(line, name) == 0) { - found = 1; - break; - } - } - fclose(fd); - } else { - return(2); - } - return (found); -} - -/* - * This function is needed for PAM. - */ - -#ifdef USE_PAM -static char *PAM_username = ""; -static char *PAM_password = ""; - -#ifdef PAM_ESTABLISH_CRED /* new PAM defines :(^ */ -#define MY_PAM_STRERROR(err_code) (char *) pam_strerror(pamh,err_code) -#else -#define MY_PAM_STRERROR(err_code) (char *) pam_strerror(err_code) -#endif - -static int pam_conv (int num_msg, - const struct pam_message **msg, - struct pam_response **resp, - void *appdata_ptr) -{ - int count = 0, replies = 0; - struct pam_response *reply = NULL; - int size = 0; - - for (count = 0; count < num_msg; count++) - { - size += sizeof (struct pam_response); - reply = realloc (reply, size); /* ANSI: is malloc() if reply==NULL */ - if (!reply) - return PAM_CONV_ERR; - - switch (msg[count]->msg_style) - { - case PAM_PROMPT_ECHO_ON: - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies++].resp = strdup(PAM_username); /* never NULL */ - break; - - case PAM_PROMPT_ECHO_OFF: - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies++].resp = strdup(PAM_password); /* never NULL */ - break; - - case PAM_TEXT_INFO: - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies++].resp = NULL; - break; - - case PAM_ERROR_MSG: - default: - free (reply); - return PAM_CONV_ERR; - } - } - - if (resp) - *resp = reply; - else - free (reply); - - return PAM_SUCCESS; -} -#endif - -/* - * plogin - Check the user name and password against the system - * password database, and login the user if OK. - * - * returns: - * UPAP_AUTHNAK: Login failed. - * UPAP_AUTHACK: Login succeeded. - * In either case, msg points to an appropriate message. - * - * UPAP_AUTHACK should only be returned *after* wtmp and utmp are updated. - */ - -static int -plogin(char *user, char *passwd, char **msg, int *msglen) -{ - -#ifdef USE_PAM - - struct pam_conv pam_conversation; - pam_handle_t *pamh; - int pam_error; -/* - * Fill the pam_conversion structure - */ - memset (&pam_conversation, '\0', sizeof (struct pam_conv)); - pam_conversation.conv = &pam_conv; - - pam_error = pam_start ("ppp", user, &pam_conversation, &pamh); - - if (pam_error != PAM_SUCCESS) { - *msg = MY_PAM_STRERROR (pam_error); - return UPAP_AUTHNAK; - } -/* - * Define the fields for the credintial validation - */ - pam_set_item (pamh, PAM_TTY, devnam); - PAM_username = user; - PAM_password = passwd; -/* - * Validate the user - */ - pam_error = pam_authenticate (pamh, PAM_SILENT); - if (pam_error == PAM_SUCCESS) { - pam_error = pam_acct_mgmt (pamh, PAM_SILENT); - - /* start a session for this user. Session closed when link ends. */ - if (pam_error == PAM_SUCCESS) - pam_open_session (pamh, PAM_SILENT); - } - - *msg = MY_PAM_STRERROR (pam_error); - - PAM_username = - PAM_password = ""; -/* - * Clean up the mess - */ - pam_end (pamh, pam_error); - - if (pam_error != PAM_SUCCESS) - return UPAP_AUTHNAK; -/* - * Use the non-PAM methods directly - */ -#else /* #ifdef USE_PAM */ - - struct passwd *pw; - struct utmp utmp; - struct timeval tp; - char *tty, *cryptpw; - -#ifdef HAS_SHADOW - struct spwd *spwd; - struct spwd *getspnam(); -#endif - - pw = getpwnam(user); - endpwent(); - if (pw == NULL) { - return (UPAP_AUTHNAK); - } -/* - * Check that the user is not listed in /etc/ppp/ppp.deny - * and that the user's shell is listed in /etc/ppp/ppp.shells - * if /etc/ppp/ppp.shells exists. - */ - - if (checkfile(_PATH_PPPDENY, user) == 1) { - syslog(LOG_WARNING, "upap user %s: login denied in %s", - user, _PATH_PPPDENY); - return (UPAP_AUTHNAK); - } - - if (checkfile(_PATH_PPPSHELLS, pw->pw_shell) == 0) { - syslog(LOG_WARNING, "upap user %s: shell %s not in %s", - user, pw->pw_shell, _PATH_PPPSHELLS); - return (UPAP_AUTHNAK); - } - -#ifdef HAS_SHADOW - spwd = getspnam(user); - endspent(); - if (spwd) { - /* check the age of the password entry */ - long 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)) { - syslog(LOG_WARNING, "Password for %s has expired", user); - return (UPAP_AUTHNAK); - } - pw->pw_passwd = spwd->sp_pwdp; - } -#endif - - /* - * If no passwd, don't let them login. - */ - if (pw->pw_passwd == NULL || *pw->pw_passwd == '\0' || passwd == NULL) - return (UPAP_AUTHNAK); - cryptpw = crypt(passwd, pw->pw_passwd); - if (cryptpw == NULL || strcmp(cryptpw, pw->pw_passwd) != 0) - return (UPAP_AUTHNAK); - - if (pw->pw_expire) { - gettimeofday(&tp, NULL); - if (tp.tv_sec >= pw->pw_expire) { - syslog(LOG_INFO, "pap user %s account expired", user); - return (UPAP_AUTHNAK); - } - } - - /* These functions are not enabled for PAM. The reason for this is that */ - /* there is not necessarily a "passwd" entry for this user. That is */ - /* real purpose of 'PAM' -- to virtualize the account data from the */ - /* application. If you want to do the same thing, write the entry in */ - /* the 'session' hook. */ - - /* Log in wtmp and utmp using login() */ - - tty = devnam; - if (strncmp(tty, _PATH_DEV, sizeof _PATH_DEV - 1) == 0) - tty += 5; - - if (logout(tty)) /* Already entered (by login?) */ - logwtmp(tty, "", ""); - -#if defined(_PATH_LASTLOG) - { - struct lastlog ll; - int fd; - - if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) { - lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET); - memset((void *)&ll, 0, sizeof(ll)); - time(&ll.ll_time); - strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); - write(fd, (char *)&ll, sizeof(ll)); - close(fd); - } - } -#endif - - memset((void *)&utmp, 0, sizeof(utmp)); - time(&utmp.ut_time); - strncpy(utmp.ut_name, user, sizeof(utmp.ut_name)); - strncpy(utmp.ut_host, ":PPP", sizeof(utmp.ut_host)); - strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line)); - login(&utmp); /* This logs us in wtmp too */ - -#endif /* #ifdef USE_PAM */ - - syslog(LOG_INFO, "user %s logged in", user); - logged_in = TRUE; - - return (UPAP_AUTHACK); -} - -/* - * plogout - Logout the user. - */ -static void -plogout(void) -{ -#ifdef USE_PAM - struct pam_conv pam_conversation; - pam_handle_t *pamh; - int pam_error; -/* - * Fill the pam_conversion structure. The PAM specification states that the - * session must be able to be closed by a totally different handle from which - * it was created. Hold the PAM group to their own specification! - */ - memset (&pam_conversation, '\0', sizeof (struct pam_conv)); - pam_conversation.conv = &pam_conv; - - pam_error = pam_start ("ppp", user, &pam_conversation, &pamh); - if (pam_error == PAM_SUCCESS) { - pam_set_item (pamh, PAM_TTY, devnam); - pam_close_session (pamh, PAM_SILENT); - pam_end (pamh, PAM_SUCCESS); - } - -#else - char *tty; - - tty = devnam; - if (strncmp(tty, _PATH_DEV, sizeof _PATH_DEV - 1) == 0) - tty += 5; - logwtmp(tty, "", ""); /* Wipe out wtmp logout entry */ - logout(tty); /* Wipe out utmp */ -#endif - - logged_in = FALSE; -} - - -/* - * 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; - char secret[MAXWORDLEN]; - - /* - * Open the file of pap secrets and scan for a suitable secret. - * We don't accept a wildcard client. - */ - filename = _PATH_UPAPFILE; - addrs = NULL; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - check_access(f, filename); - - i = scan_authfile(f, "", our_name, (u_int32_t)0, secret, &addrs, filename); - ret = i >= 0 && (i & NONWILD_CLIENT) != 0 && secret[0] == 0; - BZERO(secret, sizeof(secret)); - - if (ret) - set_allowed_addrs(unit, addrs); - else - free_wordlist(addrs); - - fclose(f); - 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. - */ -static int -get_pap_passwd(char *passwd) -{ - char *filename; - FILE *f; - int ret; - struct wordlist *addrs; - char secret[MAXWORDLEN]; - - filename = _PATH_UPAPFILE; - addrs = NULL; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - check_access(f, filename); - ret = scan_authfile(f, user, - remote_name[0]? remote_name: NULL, - (u_int32_t)0, secret, NULL, filename); - fclose(f); - if (ret < 0) - return 0; - if (passwd != NULL) { - strncpy(passwd, secret, MAXSECRETLEN); - passwd[MAXSECRETLEN-1] = 0; - } - 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(void) -{ - FILE *f; - int ret; - char *filename; - ipcp_options *ipwo = &ipcp_wantoptions[0]; - u_int32_t remote; - - filename = _PATH_UPAPFILE; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - - remote = ipwo->accept_remote? 0: ipwo->hisaddr; - ret = scan_authfile(f, NULL, our_name, remote, NULL, NULL, filename); - fclose(f); - if (ret < 0) - return 0; - - return 1; -} - - -/* - * 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, u_int32_t remote) -{ - FILE *f; - int ret; - char *filename; - - filename = _PATH_CHAPFILE; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - - if (client[0] == 0) - client = NULL; - else if (server[0] == 0) - server = NULL; - - ret = scan_authfile(f, client, server, remote, NULL, NULL, filename); - fclose(f); - if (ret < 0) - return 0; - - return 1; -} - - -/* - * 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 save_addrs) -{ - FILE *f; - int ret, len; - char *filename; - struct wordlist *addrs; - char secbuf[MAXWORDLEN]; - - filename = _PATH_CHAPFILE; - addrs = NULL; - secbuf[0] = 0; - - f = fopen(filename, "r"); - if (f == NULL) { - syslog(LOG_ERR, "Can't open chap secret file %s: %m", filename); - return 0; - } - check_access(f, filename); - - ret = scan_authfile(f, client, server, (u_int32_t)0, - secbuf, &addrs, filename); - fclose(f); - if (ret < 0) - return 0; - - if (save_addrs) - set_allowed_addrs(unit, addrs); - - len = strlen(secbuf); - if (len > MAXSECRETLEN) { - syslog(LOG_ERR, "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; -} - -/* - * set_allowed_addrs() - set the list of allowed addresses. - */ -static void -set_allowed_addrs(int unit, struct wordlist *addrs) -{ - if (addresses[unit] != NULL) - free_wordlist(addresses[unit]); - addresses[unit] = addrs; - - /* - * If there's only one authorized address we might as well - * ask our peer for that one right away - */ - if (addrs != NULL && addrs->next == NULL) { - char *p = addrs->word; - struct ipcp_options *wo = &ipcp_wantoptions[unit]; - u_int32_t a; - struct hostent *hp; - - if (*p != '!' && *p != '-' && strchr(p, '/') == NULL) { - hp = gethostbyname(p); - if (hp != NULL && hp->h_addrtype == AF_INET) - a = *(u_int32_t *)hp->h_addr; - else - a = inet_addr(p); - if (a != (u_int32_t) -1) - wo->hisaddr = a; - } - } -} - -static void -auth_set_ip_addr(int unit) -{ - struct wordlist *addrs; - - if (non_wildclient && (addrs = addresses[unit]) != NULL) { - for (; addrs != NULL; addrs = addrs->next) { - /* Look for address overrides, and set them if we have any */ - if (strchr(addrs->word, ':') != NULL) { - if (setipaddr(addrs->word)) - break; - } - } - } -} - -/* - * 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) -{ - return ip_addr_check(addr, addresses[unit]); -} - -static int -ip_addr_check(u_int32_t addr, struct wordlist *addrs) -{ - int x, y; - u_int32_t a, mask, ah; - int accept; - char *ptr_word, *ptr_mask; - struct hostent *hp; - struct netent *np; - - /* don't allow loopback or multicast address */ - if (bad_ip_adrs(addr)) - return 0; - - if (addrs == NULL) - return !auth_required; /* no addresses authorized */ - - x = y = 0; - for (; addrs != NULL; addrs = addrs->next) { - y++; - /* "-" means no addresses authorized, "*" means any address allowed */ - ptr_word = addrs->word; - if (strcmp(ptr_word, "-") == 0) - break; - if (strcmp(ptr_word, "*") == 0) - return 1; - - /* - * A colon in the string means that we wish to force a specific - * local:remote address, but we ignore these for now. - */ - if (strchr(addrs->word, ':') != NULL) - x++; - else { - - accept = 1; - if (*ptr_word == '!') { - accept = 0; - ++ptr_word; - } - - mask = ~ (u_int32_t) 0; - ptr_mask = strchr (ptr_word, '/'); - if (ptr_mask != NULL) { - int bit_count; - - bit_count = (int) strtol (ptr_mask+1, NULL, 10); - if (bit_count <= 0 || bit_count > 32) { - syslog (LOG_WARNING, - "invalid address length %s in auth. address list", - ptr_mask); - continue; - } - *ptr_mask = '\0'; - mask <<= 32 - 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 (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) - syslog (LOG_WARNING, - "unknown host %s in auth. address list", - addrs->word); - else - /* Here a and addr are in network byte order, - and mask is in host order. */ - if (((addr ^ a) & htonl(mask)) == 0) - return accept; - } /* else */ - } - return x == y; /* not in list => can't have it */ -} - -/* - * bad_ip_adrs - return 1 if the IP address is one we don't want - * to use, such as an address in the loopback net or a multicast address. - * addr is in network byte order. - */ -int -bad_ip_adrs(u_int32_t addr) -{ - addr = ntohl(addr); - return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET - || IN_MULTICAST(addr) || IN_BADCLASS(addr); -} - -/* - * check_access - complain if a secret file has too-liberal permissions. - */ -void -check_access(FILE *f, char *filename) -{ - struct stat sbuf; - - if (fstat(fileno(f), &sbuf) < 0) { - syslog(LOG_WARNING, "cannot stat secret file %s: %m", filename); - } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { - syslog(LOG_WARNING, "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 (i.e. address authorization - * info) are placed in a wordlist and returned in *addrs. - */ -static int -scan_authfile(FILE *f, char *client, char *server, u_int32_t ipaddr, - char *secret, struct wordlist **addrs, char *filename) -{ - int newline, xxx; - int got_flag, best_flag; - FILE *sf; - struct wordlist *ap, *addr_list, *alist, *alast; - char word[MAXWORDLEN]; - char atfile[MAXWORDLEN]; - char lsecret[MAXWORDLEN]; - - if (addrs != NULL) - *addrs = 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 (server != NULL && strcmp(word, server) != 0 && !ISWILD(word)) - continue; - if (!ISWILD(word)) - 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; - - /* - * Special syntax: @filename means read secret from file. - */ - if (word[0] == '@') { - strcpy(atfile, word+1); - if ((sf = fopen(atfile, "r")) == NULL) { - syslog(LOG_WARNING, "can't open indirect secret file %s", - atfile); - continue; - } - check_access(sf, atfile); - if (!getword(sf, word, &xxx, atfile)) { - syslog(LOG_WARNING, "no secret in indirect secret file %s", - atfile); - fclose(sf); - continue; - } - fclose(sf); - } - if (secret != NULL) - strcpy(lsecret, word); - - /* - * Now read address authorization info and make a wordlist. - */ - alist = alast = NULL; - for (;;) { - if (!getword(f, word, &newline, filename) || newline) - break; - ap = (struct wordlist *) malloc(sizeof(struct wordlist) - + strlen(word)); - if (ap == NULL) - novm("authorized addresses"); - ap->next = NULL; - strcpy(ap->word, word); - if (alist == NULL) - alist = ap; - else - alast->next = ap; - alast = ap; - } - - /* - * Check if the given IP address is allowed by the wordlist. - */ - if (ipaddr != 0 && !ip_addr_check(ipaddr, alist)) { - free_wordlist(alist); - continue; - } - - /* - * 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) - strcpy(secret, lsecret); - - if (!newline) - break; - } - - if (addrs != NULL) - *addrs = addr_list; - else if (addr_list != NULL) - free_wordlist(addr_list); - - non_wildclient = (best_flag & NONWILD_CLIENT) && client != NULL && - *client != '\0'; - return best_flag; -} - -/* - * 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 - 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 { - sprintf(struid, "%d", getuid()); - user_name = struid; - } - sprintf(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] = NULL; - - run_program(script, argv, 0); -} diff --git a/usr.sbin/pppd/cbcp.c b/usr.sbin/pppd/cbcp.c deleted file mode 100644 index 4ef23b0c39..0000000000 --- a/usr.sbin/pppd/cbcp.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * cbcp - Call Back Configuration Protocol. - * - * Copyright (c) 1995 Pedro Roque Marques - * 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 Pedro Roque Marques. The name of the author 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. - * - * $FreeBSD: src/usr.sbin/pppd/cbcp.c,v 1.4 1999/08/28 01:19:00 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/cbcp.c,v 1.6 2005/11/24 23:42:54 swildner Exp $ - */ - -#include -#include -#include -#include -#include - -#include "pppd.h" -#include "cbcp.h" -#include "fsm.h" -#include "lcp.h" -#include "ipcp.h" - -/* - * 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, - NULL, - NULL -}; - -cbcp_state cbcp[NUM_PPP]; - -/* internal prototypes */ - -static void cbcp_recvreq(cbcp_state *us, 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, char *pckt, int len); -static void cbcp_send(cbcp_state *us, u_char code, u_char *buf, int len); - -/* 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]; - - syslog(LOG_DEBUG, "cbcp_lowerup"); - syslog(LOG_DEBUG, "want: %d", us->us_type); - - if (us->us_type == CB_CONF_USER) - syslog(LOG_DEBUG, "phone no: %s", us->us_number); -} - -static void -cbcp_open(int unit) -{ - syslog(LOG_DEBUG, "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) { - syslog(LOG_ERR, "CBCP packet is too small"); - return; - } - - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - - if (len < CBCP_MINLEN || len > pktlen) { - syslog(LOG_ERR, "CBCP packet: invalid length"); - return; - } - - len -= CBCP_MINLEN; - - switch(code) { - case CBCP_REQ: - us->us_id = id; - cbcp_recvreq(us, inp, len); - break; - - case CBCP_RESP: - syslog(LOG_DEBUG, "CBCP_RESP received"); - break; - - case CBCP_ACK: - if (id != us->us_id) - syslog(LOG_DEBUG, "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, char *pckt, int pcktlen) -{ - u_char type, opt_len, delay, addr_type; - char address[256]; - int len = pcktlen; - - address[0] = 0; - - while (len > 1) { - syslog(LOG_DEBUG, "length: %d", len); - - GETCHAR(type, pckt); - GETCHAR(opt_len, pckt); - - if (len < opt_len) - break; - len -= opt_len; - - if (opt_len > 2) - GETCHAR(delay, pckt); - - us->us_allowed |= (1 << type); - - switch(type) { - case CB_CONF_NO: - syslog(LOG_DEBUG, "no callback allowed"); - break; - - case CB_CONF_USER: - syslog(LOG_DEBUG, "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]) - syslog(LOG_DEBUG, "address: %s", address); - } - break; - - case CB_CONF_ADMIN: - syslog(LOG_DEBUG, "user admin defined allowed"); - break; - - case CB_CONF_LIST: - break; - } - } - - 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; - - cb_type = us->us_allowed & us->us_type; - syslog(LOG_DEBUG, "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 ) ) { - syslog(LOG_DEBUG, "cbcp_resp CONF_USER"); - PUTCHAR(CB_CONF_USER, bufp); - len = 3 + 1 + strlen(us->us_number) + 1; - PUTCHAR(len , bufp); - PUTCHAR(5, bufp); /* delay */ - PUTCHAR(1, bufp); - BCOPY(us->us_number, bufp, strlen(us->us_number) + 1); - cbcp_send(us, CBCP_RESP, buf, len); - return; - } - - if (cb_type & ( 1 << CB_CONF_ADMIN ) ) { - syslog(LOG_DEBUG, "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 ) ) { - syslog(LOG_DEBUG, "cbcp_resp CONF_NO"); - PUTCHAR(CB_CONF_NO, bufp); - len = 2; - PUTCHAR(len , bufp); - cbcp_send(us, CBCP_RESP, buf, len); - (*ipcp_protent.open)(us->us_unit); - return; - } -} - -static void -cbcp_send(cbcp_state *us, u_char 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, char *pckt, int len) -{ - u_char type, delay, addr_type; - int opt_len; - char address[256]; - - if (len > 1) { - GETCHAR(type, pckt); - GETCHAR(opt_len, pckt); - - if (opt_len > len) - return; - - 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]) - syslog(LOG_DEBUG, "peer will call: %s", address); - } - } - - cbcp_up(us); -} - -extern int persist; - -/* ok peer will do callback */ -static void -cbcp_up(cbcp_state *us) -{ - persist = 0; - lcp_close(0, "Call me back, please"); -} diff --git a/usr.sbin/pppd/cbcp.h b/usr.sbin/pppd/cbcp.h deleted file mode 100644 index c2ab3f6899..0000000000 --- a/usr.sbin/pppd/cbcp.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef CBCP_H -#define CBCP_H - -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 -#endif diff --git a/usr.sbin/pppd/ccp.c b/usr.sbin/pppd/ccp.c deleted file mode 100644 index 369baa3ead..0000000000 --- a/usr.sbin/pppd/ccp.c +++ /dev/null @@ -1,1070 +0,0 @@ -/* - * ccp.c - PPP Compression Control Protocol. - * - * Copyright (c) 1994 The Australian National University. - * 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. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * 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. - * - * $FreeBSD: src/usr.sbin/pppd/ccp.c,v 1.10 1999/08/28 01:19:00 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/ccp.c,v 1.5 2005/11/24 23:42:54 swildner Exp $ - */ - -#include -#include -#include -#include - -#include "pppd.h" -#include "fsm.h" -#include "ccp.h" -#include - -/* - * 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", - 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); -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) - -/* - * 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 */ - -/* - * 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) - syslog(LOG_NOTICE, "Compression disabled by peer."); - - /* - * 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]); -} - -/* - * ccp_resetci - initialize at start of negotiation. - */ -static void -ccp_resetci(fsm *f) -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - u_char opt_buf[16]; - - *go = ccp_wantoptions[f->unit]; - all_rejected[f->unit] = 0; - - /* - * Check whether the kernel knows about the various - * compression methods we might request. - */ - 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_SIZE); - 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_SIZE); - 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? CILEN_DEFLATE: 0) - + (go->predictor_1? CILEN_PREDICTOR_1: 0) - + (go->predictor_2? CILEN_PREDICTOR_2: 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. - */ - 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; - for (;;) { - res = ccp_test(f->unit, p, CILEN_DEFLATE, 0); - if (res > 0) { - p += CILEN_DEFLATE; - break; - } - if (res < 0 || go->deflate_size <= DEFLATE_MIN_SIZE) { - 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 (;;) { - res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0); - if (res > 0) { - p += CILEN_BSD_COMPRESS; - break; - } - if (res < 0 || go->bsd_bits <= BSD_MIN_BITS) { - 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; - - 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) -{ - 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; - - 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_SIZE - || 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. - * - * XXX What should we do with any remaining options? - */ - - if (len != 0) - return 0; - - 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; - - if (go->deflate && len >= CILEN_DEFLATE - && p[0] == (go->deflate_correct? CI_DEFLATE: 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 */ - if (go->deflate_correct) - try.deflate_correct = 0; - else - try.deflate_draft = 0; - 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) { - 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]; - - 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) { - 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_SIZE) { - 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_SIZE || 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; - } - 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) { - case CI_DEFLATE: - case CI_DEFLATE_DRAFT: - if (opt2 != NULL && opt2->deflate_size != opt->deflate_size) - sprintf(result, "Deflate%s (%d/%d)", - (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), - opt->deflate_size, opt2->deflate_size); - else - sprintf(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) - sprintf(result, "BSD-Compress (%d/%d)", opt->bsd_bits, - opt2->bsd_bits); - else - sprintf(result, "BSD-Compress (%d)", opt->bsd_bits); - break; - case CI_PREDICTOR_1: - return "Predictor 1"; - case CI_PREDICTOR_2: - return "Predictor 2"; - default: - sprintf(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) { - syslog(LOG_NOTICE, "%s compression enabled", - method_name(go, ho)); - } else { - strcpy(method1, method_name(go, NULL)); - syslog(LOG_NOTICE, "%s / %s compression enabled", - method1, method_name(ho, NULL)); - } - } else - syslog(LOG_NOTICE, "%s receive compression enabled", - method_name(go, NULL)); - } else if (ANY_COMPRESS(*ho)) - syslog(LOG_NOTICE, "%s transmit compression enabled", - method_name(ho, NULL)); -} - -/* - * 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); -} - -/* - * 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) { - 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(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. - */ - syslog(LOG_ERR, "Lost compression sync: disabling compression"); - ccp_close(unit, "Lost compression sync"); - } 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; -} - diff --git a/usr.sbin/pppd/ccp.h b/usr.sbin/pppd/ccp.h deleted file mode 100644 index 8a45eba3b8..0000000000 --- a/usr.sbin/pppd/ccp.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * ccp.h - Definitions for PPP Compression Control Protocol. - * - * Copyright (c) 1994 The Australian National University. - * 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. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * 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. - * - * $FreeBSD: src/usr.sbin/pppd/ccp.h,v 1.8 1999/08/28 01:19:00 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/ccp.h,v 1.2 2003/06/17 04:30:01 dillon Exp $ - */ - -typedef struct ccp_options { - u_int bsd_compress: 1; /* do BSD Compress? */ - u_int deflate: 1; /* do Deflate? (RFC code) */ - u_int baddeflate: 1; /* do Deflate? (Magnalink!) */ - u_int predictor_1: 1; /* do Predictor-1? */ - u_int predictor_2: 1; /* do Predictor-2? */ - u_int deflate_correct: 1; /* use correct code for deflate? */ - u_int deflate_draft: 1; /* use draft RFC code for deflate? */ - u_short bsd_bits; /* # bits/code for BSD Compress */ - u_short deflate_size; /* lg(window size) for Deflate */ - u_short baddeflate_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; diff --git a/usr.sbin/pppd/chap.c b/usr.sbin/pppd/chap.c deleted file mode 100644 index 0ac63e30ad..0000000000 --- a/usr.sbin/pppd/chap.c +++ /dev/null @@ -1,829 +0,0 @@ -/* - * chap.c - Challenge Handshake Authentication Protocol. - * - * Copyright (c) 1993 The Australian National University. - * 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 Australian National University. 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. - * - * Copyright (c) 1991 Gregory M. Christy. - * 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 Gregory M. Christy. The name of the author 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. - * - * $FreeBSD: src/usr.sbin/pppd/chap.c,v 1.10 1999/08/28 01:19:01 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/chap.c,v 1.4 2005/11/24 23:42:54 swildner Exp $ - */ - -/* - * TODO: - */ - -#include -#include -#include -#include -#include -#include - -#include "pppd.h" -#include "chap.h" -#include "md5.h" -#ifdef CHAPMS -#include "chap_ms.h" -#endif - -/* - * Protocol entry points. - */ -static void ChapInit(int); -static void ChapLowerUp(int); -static void ChapLowerDown(int); -static void ChapInput(int, u_char *, int); -static void ChapProtocolReject(int); -static int ChapPrintPkt(u_char *, int, - void (*)(void *, char *, ...), void *); - -struct protent chap_protent = { - PPP_CHAP, - ChapInit, - ChapInput, - ChapProtocolReject, - ChapLowerUp, - ChapLowerDown, - NULL, - NULL, - ChapPrintPkt, - NULL, - 1, - "CHAP", - NULL, - NULL, - NULL -}; - -chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */ - -static void ChapChallengeTimeout(void *); -static void ChapResponseTimeout(void *); -static void ChapReceiveChallenge(chap_state *, u_char *, int, int); -static void ChapRechallenge(void *); -static void ChapReceiveResponse(chap_state *, u_char *, int, int); -static void ChapReceiveSuccess(chap_state *, u_char *, int, int); -static void ChapReceiveFailure(chap_state *, u_char *, int, int); -static void ChapSendStatus(chap_state *, int); -static void ChapSendChallenge(chap_state *); -static void ChapSendResponse(chap_state *); -static void ChapGenChallenge(chap_state *); - -extern double drand48(void); -extern void srand48(long); - -/* - * ChapInit - Initialize a CHAP unit. - */ -static void -ChapInit(int unit) -{ - chap_state *cstate = &chap[unit]; - - BZERO(cstate, sizeof(*cstate)); - cstate->unit = unit; - cstate->clientstate = CHAPCS_INITIAL; - cstate->serverstate = CHAPSS_INITIAL; - cstate->timeouttime = CHAP_DEFTIMEOUT; - cstate->max_transmits = CHAP_DEFTRANSMITS; - /* random number generator is initialized in magic_init */ -} - - -/* - * ChapAuthWithPeer - Authenticate us with our peer (start client). - * - */ -void -ChapAuthWithPeer(int unit, char *our_name, int digest) -{ - chap_state *cstate = &chap[unit]; - - cstate->resp_name = our_name; - cstate->resp_type = digest; - - if (cstate->clientstate == CHAPCS_INITIAL || - cstate->clientstate == CHAPCS_PENDING) { - /* lower layer isn't up - wait until later */ - cstate->clientstate = CHAPCS_PENDING; - return; - } - - /* - * We get here as a result of LCP coming up. - * So even if CHAP was open before, we will - * have to re-authenticate ourselves. - */ - cstate->clientstate = CHAPCS_LISTEN; -} - - -/* - * ChapAuthPeer - Authenticate our peer (start server). - */ -void -ChapAuthPeer(int unit, char *our_name, int digest) -{ - chap_state *cstate = &chap[unit]; - - cstate->chal_name = our_name; - cstate->chal_type = digest; - - if (cstate->serverstate == CHAPSS_INITIAL || - cstate->serverstate == CHAPSS_PENDING) { - /* lower layer isn't up - wait until later */ - cstate->serverstate = CHAPSS_PENDING; - return; - } - - ChapGenChallenge(cstate); - ChapSendChallenge(cstate); /* crank it up dude! */ - cstate->serverstate = CHAPSS_INITIAL_CHAL; -} - - -/* - * ChapChallengeTimeout - Timeout expired on sending challenge. - */ -static void -ChapChallengeTimeout(void *arg) -{ - chap_state *cstate = (chap_state *) arg; - - /* if we aren't sending challenges, don't worry. then again we */ - /* probably shouldn't be here either */ - if (cstate->serverstate != CHAPSS_INITIAL_CHAL && - cstate->serverstate != CHAPSS_RECHALLENGE) - return; - - if (cstate->chal_transmits >= cstate->max_transmits) { - /* give up on peer */ - syslog(LOG_ERR, "Peer failed to respond to CHAP challenge"); - cstate->serverstate = CHAPSS_BADAUTH; - auth_peer_fail(cstate->unit, PPP_CHAP); - return; - } - - ChapSendChallenge(cstate); /* Re-send challenge */ -} - - -/* - * ChapResponseTimeout - Timeout expired on sending response. - */ -static void -ChapResponseTimeout(void *arg) -{ - chap_state *cstate = (chap_state *) arg; - - /* if we aren't sending a response, don't worry. */ - if (cstate->clientstate != CHAPCS_RESPONSE) - return; - - ChapSendResponse(cstate); /* re-send response */ -} - - -/* - * ChapRechallenge - Time to challenge the peer again. - */ -static void -ChapRechallenge(void *arg) -{ - chap_state *cstate = (chap_state *) arg; - - /* if we aren't sending a response, don't worry. */ - if (cstate->serverstate != CHAPSS_OPEN) - return; - - ChapGenChallenge(cstate); - ChapSendChallenge(cstate); - cstate->serverstate = CHAPSS_RECHALLENGE; -} - - -/* - * ChapLowerUp - The lower layer is up. - * - * Start up if we have pending requests. - */ -static void -ChapLowerUp(int unit) -{ - chap_state *cstate = &chap[unit]; - - if (cstate->clientstate == CHAPCS_INITIAL) - cstate->clientstate = CHAPCS_CLOSED; - else if (cstate->clientstate == CHAPCS_PENDING) - cstate->clientstate = CHAPCS_LISTEN; - - if (cstate->serverstate == CHAPSS_INITIAL) - cstate->serverstate = CHAPSS_CLOSED; - else if (cstate->serverstate == CHAPSS_PENDING) { - ChapGenChallenge(cstate); - ChapSendChallenge(cstate); - cstate->serverstate = CHAPSS_INITIAL_CHAL; - } -} - - -/* - * ChapLowerDown - The lower layer is down. - * - * Cancel all timeouts. - */ -static void -ChapLowerDown(int unit) -{ - chap_state *cstate = &chap[unit]; - - /* Timeout(s) pending? Cancel if so. */ - if (cstate->serverstate == CHAPSS_INITIAL_CHAL || - cstate->serverstate == CHAPSS_RECHALLENGE) - UNTIMEOUT(ChapChallengeTimeout, cstate); - else if (cstate->serverstate == CHAPSS_OPEN - && cstate->chal_interval != 0) - UNTIMEOUT(ChapRechallenge, cstate); - if (cstate->clientstate == CHAPCS_RESPONSE) - UNTIMEOUT(ChapResponseTimeout, cstate); - - cstate->clientstate = CHAPCS_INITIAL; - cstate->serverstate = CHAPSS_INITIAL; -} - - -/* - * ChapProtocolReject - Peer doesn't grok CHAP. - */ -static void -ChapProtocolReject(int unit) -{ - chap_state *cstate = &chap[unit]; - - if (cstate->serverstate != CHAPSS_INITIAL && - cstate->serverstate != CHAPSS_CLOSED) - auth_peer_fail(unit, PPP_CHAP); - if (cstate->clientstate != CHAPCS_INITIAL && - cstate->clientstate != CHAPCS_CLOSED) - auth_withpeer_fail(unit, PPP_CHAP); - ChapLowerDown(unit); /* shutdown chap */ -} - - -/* - * ChapInput - Input CHAP packet. - */ -static void -ChapInput(int unit, u_char *inpacket, int packet_len) -{ - chap_state *cstate = &chap[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 (packet_len < CHAP_HEADERLEN) { - CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short header.")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < CHAP_HEADERLEN) { - CHAPDEBUG((LOG_INFO, "ChapInput: rcvd illegal length.")); - return; - } - if (len > packet_len) { - CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short packet.")); - return; - } - len -= CHAP_HEADERLEN; - - /* - * Action depends on code (as in fact it usually does :-). - */ - switch (code) { - case CHAP_CHALLENGE: - ChapReceiveChallenge(cstate, inp, id, len); - break; - - case CHAP_RESPONSE: - ChapReceiveResponse(cstate, inp, id, len); - break; - - case CHAP_FAILURE: - ChapReceiveFailure(cstate, inp, id, len); - break; - - case CHAP_SUCCESS: - ChapReceiveSuccess(cstate, inp, id, len); - break; - - default: /* Need code reject? */ - syslog(LOG_WARNING, "Unknown CHAP code (%d) received.", code); - break; - } -} - - -/* - * ChapReceiveChallenge - Receive Challenge and send Response. - */ -static void -ChapReceiveChallenge(chap_state *cstate, u_char *inp, int id, int len) -{ - int rchallenge_len; - u_char *rchallenge; - int secret_len; - char secret[MAXSECRETLEN]; - char rhostname[256]; - MD5_CTX mdContext; - u_char hash[MD5_SIGNATURE_SIZE]; - - CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.", id)); - if (cstate->clientstate == CHAPCS_CLOSED || - cstate->clientstate == CHAPCS_PENDING) { - CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: in state %d", - cstate->clientstate)); - return; - } - - if (len < 2) { - CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.")); - return; - } - - GETCHAR(rchallenge_len, inp); - len -= sizeof (u_char) + rchallenge_len; /* now name field length */ - if (len < 0) { - CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.")); - return; - } - rchallenge = inp; - INCPTR(rchallenge_len, inp); - - if (len >= sizeof(rhostname)) - len = sizeof(rhostname) - 1; - BCOPY(inp, rhostname, len); - rhostname[len] = '\000'; - - CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field '%s'", - rhostname)); - - /* Microsoft doesn't send their name back in the PPP packet */ - if (remote_name[0] != 0 && (explicit_remote || rhostname[0] == 0)) { - strncpy(rhostname, remote_name, sizeof(rhostname)); - rhostname[sizeof(rhostname) - 1] = 0; - CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name", - rhostname)); - } - - /* get secret for authenticating ourselves with the specified host */ - if (!get_secret(cstate->unit, cstate->resp_name, rhostname, - secret, &secret_len, 0)) { - secret_len = 0; /* assume null secret if can't find one */ - syslog(LOG_WARNING, "No CHAP secret found for authenticating us to %s", - rhostname); - } - - /* cancel response send timeout if necessary */ - if (cstate->clientstate == CHAPCS_RESPONSE) - UNTIMEOUT(ChapResponseTimeout, cstate); - - cstate->resp_id = id; - cstate->resp_transmits = 0; - - /* generate MD based on negotiated type */ - switch (cstate->resp_type) { - - case CHAP_DIGEST_MD5: - MD5Init(&mdContext); - MD5Update(&mdContext, &cstate->resp_id, 1); - MD5Update(&mdContext, secret, secret_len); - MD5Update(&mdContext, rchallenge, rchallenge_len); - MD5Final(hash, &mdContext); - BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE); - cstate->resp_length = MD5_SIGNATURE_SIZE; - break; - -#ifdef CHAPMS - case CHAP_MICROSOFT: - ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len); - break; -#endif - - default: - CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->resp_type)); - return; - } - - BZERO(secret, sizeof(secret)); - ChapSendResponse(cstate); -} - - -/* - * ChapReceiveResponse - Receive and process response. - */ -static void -ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len) -{ - u_char *remmd, remmd_len; - int secret_len, old_state; - int code; - char rhostname[256]; - MD5_CTX mdContext; - char secret[MAXSECRETLEN]; - u_char hash[MD5_SIGNATURE_SIZE]; - - CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: Rcvd id %d.", id)); - - if (cstate->serverstate == CHAPSS_CLOSED || - cstate->serverstate == CHAPSS_PENDING) { - CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: in state %d", - cstate->serverstate)); - return; - } - - if (id != cstate->chal_id) - return; /* doesn't match ID of last challenge */ - - /* - * If we have received a duplicate or bogus Response, - * we have to send the same answer (Success/Failure) - * as we did for the first Response we saw. - */ - if (cstate->serverstate == CHAPSS_OPEN) { - ChapSendStatus(cstate, CHAP_SUCCESS); - return; - } - if (cstate->serverstate == CHAPSS_BADAUTH) { - ChapSendStatus(cstate, CHAP_FAILURE); - return; - } - - if (len < 2) { - CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.")); - return; - } - GETCHAR(remmd_len, inp); /* get length of MD */ - remmd = inp; /* get pointer to MD */ - INCPTR(remmd_len, inp); - - len -= sizeof (u_char) + remmd_len; - if (len < 0) { - CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.")); - return; - } - - UNTIMEOUT(ChapChallengeTimeout, cstate); - - if (len >= sizeof(rhostname)) - len = sizeof(rhostname) - 1; - BCOPY(inp, rhostname, len); - rhostname[len] = '\000'; - - CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: received name field: %s", - rhostname)); - - /* - * Get secret for authenticating them with us, - * do the hash ourselves, and compare the result. - */ - code = CHAP_FAILURE; - if (!get_secret(cstate->unit, rhostname, cstate->chal_name, - secret, &secret_len, 1)) { - syslog(LOG_WARNING, "No CHAP secret found for authenticating %s", - rhostname); - } else { - - /* generate MD based on negotiated type */ - switch (cstate->chal_type) { - - case CHAP_DIGEST_MD5: /* only MD5 is defined for now */ - if (remmd_len != MD5_SIGNATURE_SIZE) - break; /* it's not even the right length */ - MD5Init(&mdContext); - MD5Update(&mdContext, &cstate->chal_id, 1); - MD5Update(&mdContext, secret, secret_len); - MD5Update(&mdContext, cstate->challenge, cstate->chal_len); - MD5Final(hash, &mdContext); - - /* compare local and remote MDs and send the appropriate status */ - if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0) - code = CHAP_SUCCESS; /* they are the same! */ - break; - - default: - CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->chal_type)); - } - } - - BZERO(secret, sizeof(secret)); - ChapSendStatus(cstate, code); - - if (code == CHAP_SUCCESS) { - old_state = cstate->serverstate; - cstate->serverstate = CHAPSS_OPEN; - if (old_state == CHAPSS_INITIAL_CHAL) { - auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len); - } - if (cstate->chal_interval != 0) - TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval); - syslog(LOG_NOTICE, "CHAP peer authentication succeeded for %s", - rhostname); - - } else { - syslog(LOG_ERR, "CHAP peer authentication failed for remote host %s", - rhostname); - cstate->serverstate = CHAPSS_BADAUTH; - auth_peer_fail(cstate->unit, PPP_CHAP); - } -} - -/* - * ChapReceiveSuccess - Receive Success - */ -static void -ChapReceiveSuccess(chap_state *cstate, u_char *inp, int id, int len) -{ - - CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: Rcvd id %d.", id)); - - if (cstate->clientstate == CHAPCS_OPEN) - /* presumably an answer to a duplicate response */ - return; - - if (cstate->clientstate != CHAPCS_RESPONSE) { - /* don't know what this is */ - CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: in state %d\n", - cstate->clientstate)); - return; - } - - UNTIMEOUT(ChapResponseTimeout, cstate); - - /* - * Print message. - */ - if (len > 0) - PRINTMSG(inp, len); - - cstate->clientstate = CHAPCS_OPEN; - - auth_withpeer_success(cstate->unit, PPP_CHAP); -} - - -/* - * ChapReceiveFailure - Receive failure. - */ -static void -ChapReceiveFailure(chap_state *cstate, u_char *inp, int id, int len) -{ - CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: Rcvd id %d.", id)); - - if (cstate->clientstate != CHAPCS_RESPONSE) { - /* don't know what this is */ - CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: in state %d\n", - cstate->clientstate)); - return; - } - - UNTIMEOUT(ChapResponseTimeout, cstate); - - /* - * Print message. - */ - if (len > 0) - PRINTMSG(inp, len); - - syslog(LOG_ERR, "CHAP authentication failed"); - auth_withpeer_fail(cstate->unit, PPP_CHAP); -} - - -/* - * ChapSendChallenge - Send an Authenticate challenge. - */ -static void -ChapSendChallenge(chap_state *cstate) -{ - u_char *outp; - int chal_len, name_len; - int outlen; - - chal_len = cstate->chal_len; - name_len = strlen(cstate->chal_name); - outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len; - outp = outpacket_buf; - - MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */ - - PUTCHAR(CHAP_CHALLENGE, outp); - PUTCHAR(cstate->chal_id, outp); - PUTSHORT(outlen, outp); - - PUTCHAR(chal_len, outp); /* put length of challenge */ - BCOPY(cstate->challenge, outp, chal_len); - INCPTR(chal_len, outp); - - BCOPY(cstate->chal_name, outp, name_len); /* append hostname */ - - output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN); - - CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.", cstate->chal_id)); - - TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime); - ++cstate->chal_transmits; -} - - -/* - * ChapSendStatus - Send a status response (ack or nak). - */ -static void -ChapSendStatus(chap_state *cstate, int code) -{ - u_char *outp; - int outlen, msglen; - char msg[256]; - - if (code == CHAP_SUCCESS) - sprintf(msg, "Welcome to %s.", hostname); - else - sprintf(msg, "I don't like you. Go 'way."); - msglen = strlen(msg); - - outlen = CHAP_HEADERLEN + msglen; - outp = outpacket_buf; - - MAKEHEADER(outp, PPP_CHAP); /* paste in a header */ - - PUTCHAR(code, outp); - PUTCHAR(cstate->chal_id, outp); - PUTSHORT(outlen, outp); - BCOPY(msg, outp, msglen); - output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN); - - CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.", code, - cstate->chal_id)); -} - -/* - * ChapGenChallenge is used to generate a pseudo-random challenge string of - * a pseudo-random length between min_len and max_len. The challenge - * string and its length are stored in *cstate, and various other fields of - * *cstate are initialized. - */ - -static void -ChapGenChallenge(chap_state *cstate) -{ - int chal_len; - u_char *ptr = cstate->challenge; - unsigned int i; - - /* pick a random challenge length between MIN_CHALLENGE_LENGTH and - MAX_CHALLENGE_LENGTH */ - chal_len = (unsigned) ((drand48() * - (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) + - MIN_CHALLENGE_LENGTH); - cstate->chal_len = chal_len; - cstate->chal_id = ++cstate->id; - cstate->chal_transmits = 0; - - /* generate a random string */ - for (i = 0; i < chal_len; i++ ) - *ptr++ = (char) (drand48() * 0xff); -} - -/* - * ChapSendResponse - send a response packet with values as specified - * in *cstate. - */ -/* ARGSUSED */ -static void -ChapSendResponse(chap_state *cstate) -{ - u_char *outp; - int outlen, md_len, name_len; - - md_len = cstate->resp_length; - name_len = strlen(cstate->resp_name); - outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len; - outp = outpacket_buf; - - MAKEHEADER(outp, PPP_CHAP); - - PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */ - PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */ - PUTSHORT(outlen, outp); /* packet length */ - - PUTCHAR(md_len, outp); /* length of MD */ - BCOPY(cstate->response, outp, md_len); /* copy MD to buffer */ - INCPTR(md_len, outp); - - BCOPY(cstate->resp_name, outp, name_len); /* append our name */ - - /* send the packet */ - output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN); - - cstate->clientstate = CHAPCS_RESPONSE; - TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime); - ++cstate->resp_transmits; -} - -/* - * ChapPrintPkt - print the contents of a CHAP packet. - */ -static char *ChapCodenames[] = { - "Challenge", "Response", "Success", "Failure" -}; - -static int -ChapPrintPkt(u_char *p, int plen, void (*printer)(void *, char *, ...), - void *arg) -{ - int code, id, len; - int clen, nlen; - u_char x; - - if (plen < CHAP_HEADERLEN) - return 0; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < CHAP_HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *)) - printer(arg, " %s", ChapCodenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= CHAP_HEADERLEN; - 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_HEADERLEN; -} diff --git a/usr.sbin/pppd/chap.h b/usr.sbin/pppd/chap.h deleted file mode 100644 index 4c9fa60b62..0000000000 --- a/usr.sbin/pppd/chap.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * chap.h - Challenge Handshake Authentication Protocol definitions. - * - * Copyright (c) 1993 The Australian National University. - * 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 Australian National University. 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. - * - * Copyright (c) 1991 Gregory M. Christy - * 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 author. - * - * 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. - * - * $FreeBSD: src/usr.sbin/pppd/chap.h,v 1.7 1999/08/28 01:19:01 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/chap.h,v 1.3 2003/11/03 19:31:40 eirikn Exp $ - */ - -#ifndef __CHAP_INCLUDE__ - -/* Code + ID + length */ -#define CHAP_HEADERLEN 4 - -/* - * CHAP codes. - */ - -#define CHAP_DIGEST_MD5 5 /* use MD5 algorithm */ -#define MD5_SIGNATURE_SIZE 16 /* 16 bytes in a MD5 message digest */ -#define CHAP_MICROSOFT 0x80 /* use Microsoft-compatible alg. */ -#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */ - -#define CHAP_CHALLENGE 1 -#define CHAP_RESPONSE 2 -#define CHAP_SUCCESS 3 -#define CHAP_FAILURE 4 - -/* - * Challenge lengths (for challenges we send) and other limits. - */ -#define MIN_CHALLENGE_LENGTH 32 -#define MAX_CHALLENGE_LENGTH 64 -#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 or MS-CHAP */ - -/* - * Each interface is described by a chap structure. - */ - -typedef struct chap_state { - int unit; /* Interface unit number */ - int clientstate; /* Client state */ - int serverstate; /* Server state */ - u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */ - u_char chal_len; /* challenge length */ - u_char chal_id; /* ID of last challenge */ - u_char chal_type; /* hash algorithm for challenges */ - u_char id; /* Current id */ - char *chal_name; /* Our name to use with challenge */ - int chal_interval; /* Time until we challenge peer again */ - int timeouttime; /* Timeout time in seconds */ - int max_transmits; /* Maximum # of challenge transmissions */ - int chal_transmits; /* Number of transmissions of challenge */ - int resp_transmits; /* Number of transmissions of response */ - u_char response[MAX_RESPONSE_LENGTH]; /* Response to send */ - u_char resp_length; /* length of response */ - u_char resp_id; /* ID for response messages */ - u_char resp_type; /* hash algorithm for responses */ - char *resp_name; /* Our name to send with response */ -} chap_state; - - -/* - * Client (peer) states. - */ -#define CHAPCS_INITIAL 0 /* Lower layer down, not opened */ -#define CHAPCS_CLOSED 1 /* Lower layer up, not opened */ -#define CHAPCS_PENDING 2 /* Auth us to peer when lower up */ -#define CHAPCS_LISTEN 3 /* Listening for a challenge */ -#define CHAPCS_RESPONSE 4 /* Sent response, waiting for status */ -#define CHAPCS_OPEN 5 /* We've received Success */ - -/* - * Server (authenticator) states. - */ -#define CHAPSS_INITIAL 0 /* Lower layer down, not opened */ -#define CHAPSS_CLOSED 1 /* Lower layer up, not opened */ -#define CHAPSS_PENDING 2 /* Auth peer when lower up */ -#define CHAPSS_INITIAL_CHAL 3 /* We've sent the first challenge */ -#define CHAPSS_OPEN 4 /* We've sent a Success msg */ -#define CHAPSS_RECHALLENGE 5 /* We've sent another challenge */ -#define CHAPSS_BADAUTH 6 /* We've sent a Failure msg */ - -/* - * Timeouts. - */ -#define CHAP_DEFTIMEOUT 3 /* Timeout time in seconds */ -#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ - -extern chap_state chap[]; - -void ChapAuthWithPeer(int, char *, int); -void ChapAuthPeer(int, char *, int); - -extern struct protent chap_protent; - -#define __CHAP_INCLUDE__ -#endif /* __CHAP_INCLUDE__ */ diff --git a/usr.sbin/pppd/chap_ms.c b/usr.sbin/pppd/chap_ms.c deleted file mode 100644 index 52af75df6b..0000000000 --- a/usr.sbin/pppd/chap_ms.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * chap_ms.c - Microsoft MS-CHAP compatible implementation. - * - * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited. - * http://www.strataware.com/ - * - * 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 Eric Rosenquist. The name of the author 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. - * - * $FreeBSD: src/usr.sbin/pppd/chap_ms.c,v 1.8 2000/02/24 21:10:28 markm Exp $ - * $DragonFly: src/usr.sbin/pppd/chap_ms.c,v 1.5 2005/11/24 23:42:54 swildner Exp $ - */ - -/* - * 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 - */ - -#ifdef CHAPMS - -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_CRYPT_H -#include -#endif - -#include "pppd.h" -#include "chap.h" -#include "chap_ms.h" -#include "md4.h" - -#ifndef USE_CRYPT -#include -#endif - -typedef struct { - u_char LANManResp[24]; - u_char NTResp[24]; - u_char UseNT; /* If 1, ignore the LANMan response field */ -} MS_ChapResponse; -/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse), - in case this struct gets padded. */ - - -static void ChallengeResponse(u_char *, u_char *, u_char *); -static void DesEncrypt(u_char *, u_char *, u_char *); -static void MakeKey(u_char *, u_char *); -static u_char Get7Bits(u_char *, int); -static void ChapMS_NT(char *, int, char *, int, MS_ChapResponse *); -#ifdef MSLANMAN -static void ChapMS_LANMan(char *, int, char *, int, MS_ChapResponse *); -#endif - -#ifdef USE_CRYPT -static void Expand(u_char *, u_char *); -static void Collapse(u_char *, u_char *); -#endif - -/* - * Parameters: - * challenge: IN 8 octets - * pwHash: IN 16 octets - * response: OUT 24 octets - */ -static void -ChallengeResponse(u_char *challenge, u_char *pwHash, u_char *response) -{ - char ZPasswordHash[21]; - - BZERO(ZPasswordHash, sizeof(ZPasswordHash)); - BCOPY(pwHash, ZPasswordHash, MD4_SIGNATURE_SIZE); - -#if 0 - log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG); -#endif - - DesEncrypt(challenge, ZPasswordHash + 0, response + 0); - DesEncrypt(challenge, ZPasswordHash + 7, response + 8); - DesEncrypt(challenge, ZPasswordHash + 14, response + 16); - -#if 0 - log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG); -#endif -} - - -#ifdef USE_CRYPT -/* - * Parameters: - * clear: IN 8 octets - * key: IN 7 octets - * cipher: OUT 8 octets - */ -static void -DesEncrypt(u_char *clear, u_char *key, u_char *cipher) -{ - u_char des_key[8]; - u_char crypt_key[66]; - u_char des_input[66]; - - MakeKey(key, des_key); - - Expand(des_key, crypt_key); - setkey(crypt_key); - -#if 0 - CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X", - clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7])); -#endif - - Expand(clear, des_input); - encrypt(des_input, 0); - Collapse(des_input, cipher); - -#if 0 - CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X", - cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7])); -#endif -} - -#else /* USE_CRYPT */ - -/* - * Parameters: - * clear: IN 8 octets - * key: IN 7 octets - * cipher: OUT 8 octets - */ -static void -DesEncrypt(u_char *clear, u_char *key, u_char *cipher) -{ - DES_cblock des_key; - DES_key_schedule key_schedule; - - MakeKey(key, des_key); - - DES_set_key(&des_key, &key_schedule); - -#if 0 - CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X", - clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7])); -#endif - - DES_ecb_encrypt((DES_cblock *)clear, (DES_cblock *)cipher, &key_schedule, 1); - -#if 0 - CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X", - cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7])); -#endif -} - -#endif /* USE_CRYPT */ - - -static u_char -Get7Bits(u_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; -} - -#ifdef USE_CRYPT - -/* in == 8-byte string (expanded version of the 56-bit key) - * out == 64-byte string where each byte is either 1 or 0 - * Note that the low-order "bit" is always ignored by by setkey() - */ -static void -Expand(u_char *in, u_char *out) -{ - int j, c; - int i; - - for(i = 0; i < 64; in++){ - c = *in; - for(j = 7; j >= 0; j--) - *out++ = (c >> j) & 01; - i += 8; - } -} - -/* The inverse of Expand - */ -static void -Collapse(u_char *in, u_char *out) -{ - int j; - int i; - unsigned int c; - - for (i = 0; i < 64; i += 8, out++) { - c = 0; - for (j = 7; j >= 0; j--, in++) - c |= *in << j; - *out = c & 0xff; - } -} -#endif - -/* - * Parameters: - * IN 56 bit DES key missing parity bits - * OUT 64 bit DES key with parity bits added - */ -static void -MakeKey(u_char *key, u_char *des_key) -{ - 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); - -#ifndef USE_CRYPT - DES_set_odd_parity((DES_cblock *)des_key); -#endif - -#if 0 - CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X", - key[0], key[1], key[2], key[3], key[4], key[5], key[6])); - CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X", - des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7])); -#endif -} - -static void -ChapMS_NT(char *rchallenge, int rchallenge_len, char *secret, int secret_len, - MS_ChapResponse *response) -{ - int i; - MD4_CTX md4Context; - u_char hash[MD4_SIGNATURE_SIZE]; - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - - /* Initialize the Unicode version of the secret (== password). */ - /* This implicitly supports 8-bit ISO8859/1 characters. */ - BZERO(unicodePassword, sizeof(unicodePassword)); - for (i = 0; i < secret_len; i++) - unicodePassword[i * 2] = (u_char)secret[i]; - - MD4Init(&md4Context); - MD4Update(&md4Context, unicodePassword, secret_len * 2); /* Unicode is 2 bytes/char */ - - MD4Final(hash, &md4Context); /* Tell MD4 we're done */ - - ChallengeResponse(rchallenge, hash, response->NTResp); -} - -#ifdef MSLANMAN -static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ - -static void -ChapMS_LANMan(char *rchallenge, int rchallenge_len, char *secret, - int secret_len, MS_ChapResponse *response) -{ - int i; - u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - - /* LANMan password is case insensitive */ - BZERO(UcasePassword, sizeof(UcasePassword)); - for (i = 0; i < secret_len; i++) - UcasePassword[i] = (u_char)toupper(secret[i]); - DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 ); - DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 ); - ChallengeResponse(rchallenge, PasswordHash, response->LANManResp); -} -#endif - -void -ChapMS(chap_state *cstate, char *rchallenge, int rchallenge_len, char *secret, - int secret_len) -{ - MS_ChapResponse response; -#ifdef MSLANMAN - extern int ms_lanman; -#endif - -#if 0 - CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'", secret_len, secret)); -#endif - BZERO(&response, sizeof(response)); - - /* Calculate both always */ - ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response); - -#ifdef MSLANMAN - ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response); - - /* prefered method is set by option */ - response.UseNT = !ms_lanman; -#else - response.UseNT = 1; -#endif - - BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN); - cstate->resp_length = MS_CHAP_RESPONSE_LEN; -} - -#endif /* CHAPMS */ diff --git a/usr.sbin/pppd/chap_ms.h b/usr.sbin/pppd/chap_ms.h deleted file mode 100644 index d06ae5ca37..0000000000 --- a/usr.sbin/pppd/chap_ms.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * chap.h - Challenge Handshake Authentication Protocol definitions. - * - * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited. - * http://www.strataware.com/ - * - * 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 Eric Rosenquist. The name of the author 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. - * - * $FreeBSD: src/usr.sbin/pppd/chap_ms.h,v 1.5 1999/08/28 01:19:02 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/chap_ms.h,v 1.3 2003/11/03 19:31:40 eirikn Exp $ - */ - -#ifndef __CHAPMS_INCLUDE__ - -#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */ -#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */ - -void ChapMS(chap_state *, char *, int, char *, int); - -#define __CHAPMS_INCLUDE__ -#endif /* __CHAPMS_INCLUDE__ */ diff --git a/usr.sbin/pppd/demand.c b/usr.sbin/pppd/demand.c deleted file mode 100644 index 19ad1bb772..0000000000 --- a/usr.sbin/pppd/demand.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * demand.c - Support routines for demand-dialling. - * - * Copyright (c) 1993 The Australian National University. - * 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 Australian National University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/demand.c,v 1.5 1999/08/28 01:19:02 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/demand.c,v 1.4 2005/11/24 23:42:54 swildner Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef PPP_FILTER -#include -#include -#include -#endif - -#include "pppd.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_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0); - ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0); - -#ifdef PPP_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 -}; - -/* - * 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(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; - - /* log_packet(frame, len, "from loop: ", LOG_DEBUG); */ - 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_FILTER - if (active_filter.bf_len != 0 - && bpf_filter(active_filter.bf_insns, frame, len, len) == 0) - return 0; -#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 !!?? */ -} diff --git a/usr.sbin/pppd/fsm.c b/usr.sbin/pppd/fsm.c deleted file mode 100644 index d8a485300c..0000000000 --- a/usr.sbin/pppd/fsm.c +++ /dev/null @@ -1,760 +0,0 @@ -/* - * fsm.c - {Link, IP} Control Protocol Finite State Machine. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/fsm.c,v 1.8 1999/08/28 01:19:02 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/fsm.c,v 1.4 2005/11/24 23:42:54 swildner Exp $ - */ - -/* - * TODO: - * Randomize fsm id on link/init. - * Deal with variable outgoing MTU. - */ - -#include -#include -#include -#include - -#include "pppd.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((LOG_INFO, "%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((LOG_INFO, "%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; - } -} - - -/* - * 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: - 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, send Terminate-Request */ - f->retransmits = f->maxtermtransmits; - 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; - - f->state = 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) { - syslog(LOG_WARNING, "%s: timeout sending Config-Requests", - 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((LOG_INFO, "%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((LOG_WARNING, "fsm_input(%x): Rcvd short header.", - f->protocol)); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < HEADERLEN) { - FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd illegal length.", - f->protocol)); - return; - } - if (len > l) { - FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd short packet.", - f->protocol)); - return; - } - len -= HEADERLEN; /* subtract header length */ - - if( f->state == INITIAL || f->state == STARTING ){ - FSMDEBUG((LOG_INFO, "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; - - FSMDEBUG((LOG_INFO, "fsm_rconfreq(%s): Rcvd id %d.", PROTO_NAME(f), id)); - 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 */ - 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 CONFACK 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) -{ - FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d.", - PROTO_NAME(f), id)); - - 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 */ - log_packet(inp, len, "Received bad configure-ack: ", LOG_ERR); - FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)", - PROTO_NAME(f), len)); - return; - } - f->seen_ack = 1; - - 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 (*proc)(fsm *, u_char *, int); - int ret; - - FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d.", - PROTO_NAME(f), id)); - - if (id != f->reqid || f->seen_ack) /* Expected id? */ - return; /* Nope, toss... */ - proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci; - if (!proc || !(ret = proc(f, inp, len))) { - /* Nak/reject is bad - ignore it */ - log_packet(inp, len, "Received bad configure-nak/rej: ", LOG_ERR); - FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)", - PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), 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) -{ - char str[80]; - - FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d.", - PROTO_NAME(f), id)); - - switch (f->state) { - case ACKRCVD: - case ACKSENT: - f->state = REQSENT; /* Start over but keep trying */ - break; - - case OPENED: - if (len > 0) { - fmtmsg(str, sizeof(str), "%0.*v", len, p); - syslog(LOG_INFO, "%s terminated by peer (%s)", PROTO_NAME(f), str); - } else - syslog(LOG_INFO, "%s terminated by peer", PROTO_NAME(f)); - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - f->retransmits = 0; - f->state = STOPPING; - 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) -{ - FSMDEBUG((LOG_INFO, "fsm_rtermack(%s).", PROTO_NAME(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); - break; - } -} - - -/* - * fsm_rcoderej - Receive an Code-Reject. - */ -static void -fsm_rcoderej(fsm *f, u_char *inp, int len) -{ - u_char code, id; - - FSMDEBUG((LOG_INFO, "fsm_rcoderej(%s).", PROTO_NAME(f))); - - if (len < HEADERLEN) { - FSMDEBUG((LOG_INFO, "fsm_rcoderej: Rcvd short Code-Reject packet!")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - syslog(LOG_WARNING, "%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: - if( f->callbacks->down ) - (*f->callbacks->down)(f); - - /* Init restart counter, send Terminate-Request */ - f->retransmits = f->maxtermtransmits; - 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; - - f->state = STOPPING; - break; - - default: - FSMDEBUG((LOG_INFO, "%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; - } - - 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); - - FSMDEBUG((LOG_INFO, "%s: sending Configure-Request, id %d", - PROTO_NAME(f), f->reqid)); -} - - -/* - * 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); - - FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d, id %d.", - PROTO_NAME(f), code, id)); -} diff --git a/usr.sbin/pppd/fsm.h b/usr.sbin/pppd/fsm.h deleted file mode 100644 index f04dbf4acf..0000000000 --- a/usr.sbin/pppd/fsm.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/fsm.h,v 1.7 1999/08/28 01:19:03 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/fsm.h,v 1.3 2003/11/03 19:31:40 eirikn Exp $ - */ - -/* - * Packet header = Code, id, length. - */ -#define HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short)) - - -/* - * 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 */ - u_char id; /* Current id */ - u_char reqid; /* Current request id */ - u_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 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) /* Reset our Configuration Information */ - (fsm *); - int (*cilen) /* Length of our Configuration Information */ - (fsm *); - void (*addci) /* Add our Configuration Information */ - (fsm *, u_char *, int *); - int (*ackci) /* ACK our Configuration Information */ - (fsm *, u_char *, int); - int (*nakci) /* NAK our Configuration Information */ - (fsm *, u_char *, int); - int (*rejci) /* Reject our Configuration Information */ - (fsm *, u_char *, int); - int (*reqci) /* Request peer's Configuration Information */ - (fsm *, u_char *, int *, int); - void (*up) /* Called when fsm reaches OPENED state */ - (fsm *); - void (*down) /* Called when fsm leaves OPENED state */ - (fsm *); - void (*starting) /* Called when we want the lower layer */ - (fsm *); - void (*finished) /* Called when we don't want the lower layer */ - (fsm *); - void (*protreject) /* Called when Protocol-Reject received */ - (int); - void (*retransmit) /* Retransmission is necessary */ - (fsm *); - int (*extcode) /* Called when unknown code received */ - (fsm *, int, int, u_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 *, u_char *, int); -void fsm_protreject(fsm *); -void fsm_sdata(fsm *, int, int, u_char *, int); - - -/* - * Variables - */ -extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */ diff --git a/usr.sbin/pppd/ipcp.c b/usr.sbin/pppd/ipcp.c deleted file mode 100644 index ba111a8e9d..0000000000 --- a/usr.sbin/pppd/ipcp.c +++ /dev/null @@ -1,1493 +0,0 @@ -/* - * ipcp.c - PPP IP Control Protocol. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/ipcp.c,v 1.12 1999/08/28 01:19:03 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/ipcp.c,v 1.5 2007/11/25 01:28:24 swildner Exp $ - */ - -/* - * TODO: - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pppd.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 */ - -/* local vars */ -static int cis_received[NUM_PPP]; /* # Conf-Reqs received */ -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 */ - -/* - * 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); /* 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_script(fsm *, char *); /* Run an up/down script */ -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 */ -}; - -/* - * 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); - -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_check_options, - ip_demand_conf, - ip_active_pkt -}; - -static void ipcp_clear_addrs(int); - -/* - * 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") - - -/* - * Make a string representation of a network IP address. - */ -char * -ip_ntoa(u_int32_t ipaddr) -{ - static char b[64]; - - ipaddr = ntohl(ipaddr); - - sprintf(b, "%d.%d.%d.%d", - (u_char)(ipaddr >> 24), - (u_char)(ipaddr >> 16), - (u_char)(ipaddr >> 8), - (u_char)(ipaddr)); - return b; -} - - -/* - * 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]); - - memset(wo, 0, sizeof(*wo)); - memset(ao, 0, sizeof(*ao)); - - wo->neg_addr = 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 = 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_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. - */ -static void -ipcp_resetci(fsm *f) -{ - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - - wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr; - if (wo->ouraddr == 0) - wo->accept_local = 1; - if (wo->hisaddr == 0) - wo->accept_remote = 1; - ipcp_gotoptions[f->unit] = *wo; - cis_received[f->unit] = 0; -} - - -/* - * ipcp_cilen - Return length of our CI. - */ -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 LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) -#define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0) - - /* - * First see if we want to change our options to the old - * forms because we have received old forms from the peer. - */ - if (wo->neg_addr && !go->neg_addr && !go->old_addrs) { - /* use the old style of address negotiation */ - go->neg_addr = 1; - go->old_addrs = 1; - } - if (wo->neg_vj && !go->neg_vj && !go->old_vj) { - /* try an older style of VJ negotiation */ - if (cis_received[f->unit] == 0) { - /* keep trying the new style until we see some CI from the peer */ - go->neg_vj = 1; - } else { - /* 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 (LENCIADDR(go->neg_addr, go->old_addrs) + - LENCIVJ(go->neg_vj, go->old_vj)); -} - - -/* - * ipcp_addci - Add our desired CIs to a packet. - */ -static void -ipcp_addci(fsm *f, u_char *ucp, int *lenp) -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - int len = *lenp; - -#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, old, val1, val2) \ - if (neg) { \ - int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ - if (len >= addrlen) { \ - u_int32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(addrlen, ucp); \ - l = ntohl(val1); \ - PUTLONG(l, ucp); \ - if (old) { \ - l = ntohl(val2); \ - PUTLONG(l, ucp); \ - } \ - len -= addrlen; \ - } else \ - neg = 0; \ - } - - ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), 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); - - *lenp -= len; -} - - -/* - * ipcp_ackci - Ack our CIs. - * - * 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 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, old, val1, val2) \ - if (neg) { \ - int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ - u_int32_t l; \ - if ((len -= addrlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != addrlen || \ - citype != opt) \ - goto bad; \ - GETLONG(l, p); \ - cilong = htonl(l); \ - if (val1 != cilong) \ - goto bad; \ - if (old) { \ - GETLONG(l, p); \ - cilong = htonl(l); \ - if (val2 != cilong) \ - goto bad; \ - } \ - } - - ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), 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); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - return (1); - -bad: - IPCPDEBUG((LOG_INFO, "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. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int -ipcp_nakci(fsm *f, u_char *p, int len) -{ - 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; - 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 NAKCIADDR(opt, neg, old, code) \ - if (go->neg && \ - len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \ - p[1] == cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - ciaddr1 = htonl(l); \ - if (old) { \ - GETLONG(l, p); \ - ciaddr2 = htonl(l); \ - no.old_addrs = 1; \ - } else \ - ciaddr2 = 0; \ - no.neg = 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 \ - } - - /* - * Accept the peer's idea of {our,his} address, if different - * from our idea, only if the accept_{local,remote} flag is set. - */ - NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs, - if (go->accept_local && ciaddr1) { /* Do we know our address? */ - try.ouraddr = ciaddr1; - IPCPDEBUG((LOG_INFO, "local IP address %s", - ip_ntoa(ciaddr1))); - } - if (go->accept_remote && ciaddr2) { /* Does he know his? */ - try.hisaddr = ciaddr2; - IPCPDEBUG((LOG_INFO, "remote IP address %s", - ip_ntoa(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 (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; - } - } - ); - - /* - * 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. - */ - while (len > CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if( (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 = 1; - try.old_addrs = 1; - GETLONG(l, p); - ciaddr1 = htonl(l); - if (ciaddr1 && go->accept_local) - try.ouraddr = ciaddr1; - 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) - try.neg_addr = 1; - no.neg_addr = 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: - IPCPDEBUG((LOG_INFO, "ipcp_nakci: received bad Nak!")); - return 0; -} - - -/* - * ipcp_rejci - Reject some of our CIs. - */ -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 REJCIADDR(opt, neg, old, val1, val2) \ - if (go->neg && \ - len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \ - p[1] == 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; \ - if (old) { \ - GETLONG(l, p); \ - cilong = htonl(l); \ - /* Check rejected value. */ \ - if (cilong != val2) \ - goto bad; \ - } \ - try.neg = 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; \ - } - - REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, - go->old_addrs, go->ouraddr, go->hisaddr); - - REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); - - /* - * 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((LOG_INFO, "ipcp_rejci: received bad Reject!")); - return 0; -} - - -/* - * ipcp_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. - * - * Parameters: - * inp: Requested CIs - * len: Length of requested CIs - */ -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]; - ipcp_options *go = &ipcp_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 */ - 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; - - cis_received[f->unit] = 1; - - /* - * 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((LOG_INFO, "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: - IPCPDEBUG((LOG_INFO, "ipcp: received ADDRS ")); - if (!ao->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); - IPCPDEBUG((LOG_INFO, "(%s:", ip_ntoa(ciaddr1))); - 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); - IPCPDEBUG((LOG_INFO, "%s)", ip_ntoa(ciaddr2))); - if (ciaddr2 != wo->ouraddr) { - if (ciaddr2 == 0 || !wo->accept_local) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u_int32_t), p); - tl = ntohl(wo->ouraddr); - PUTLONG(tl, p); - } - } else { - go->ouraddr = ciaddr2; /* accept peer's idea */ - } - } - - ho->neg_addr = 1; - ho->old_addrs = 1; - ho->hisaddr = ciaddr1; - ho->ouraddr = ciaddr2; - break; - - case CI_ADDR: - IPCPDEBUG((LOG_INFO, "ipcp: received ADDR ")); - - if (!ao->neg_addr || - 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); - IPCPDEBUG((LOG_INFO, "(%s)", ip_ntoa(ciaddr1))); - 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; - IPCPDEBUG((LOG_INFO, "ipcp: received DNS%d Request ", d+1)); - - /* 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; - IPCPDEBUG((LOG_INFO, "ipcp: received WINS%d Request ", d+1)); - - /* If we do not have a DNS 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: - IPCPDEBUG((LOG_INFO, "ipcp: received COMPRESSTYPE ")); - if (!ao->neg_vj || - (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) { - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - IPCPDEBUG((LOG_INFO, "(%d)", cishort)); - - 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: - IPCPDEBUG((LOG_INFO, " (%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 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 && - wo->req_addr && !reject_if_disagree) { - 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((LOG_INFO, "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 && !bad_ip_adrs(local)) - wo->ouraddr = local; - } - } - - if (demand && wo->hisaddr == 0) { - option_error("remote IP address required for demand-dialling\n"); - exit(1); - } -#if 0 - if (demand && wo->accept_remote) { - option_error("ipcp-accept-remote is incompatible with demand\n"); - exit(1); - } -#endif -} - - -/* - * 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 (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr))) - return 0; - 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)) - default_route_set[u] = 1; - if (wo->proxy_arp) - if (sifproxyarp(u, wo->hisaddr)) - proxy_arp_set[u] = 1; - - syslog(LOG_NOTICE, "local IP address %s", ip_ntoa(wo->ouraddr)); - syslog(LOG_NOTICE, "remote IP address %s", ip_ntoa(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]; - - np_up(f->unit, PPP_IP); - IPCPDEBUG((LOG_INFO, "ipcp: up")); - - /* - * We must have a non-zero IP address for both ends of the link. - */ - if (!ho->neg_addr) - ho->hisaddr = wo->hisaddr; - - if (ho->hisaddr == 0) { - syslog(LOG_ERR, "Could not determine remote IP address"); - ipcp_close(f->unit, "Could not determine remote IP address"); - return; - } - if (go->ouraddr == 0) { - syslog(LOG_ERR, "Could not determine local IP address"); - ipcp_close(f->unit, "Could not determine local IP address"); - return; - } - script_setenv("IPLOCAL", ip_ntoa(go->ouraddr)); - script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr)); - - /* - * Check that the peer is allowed to use the IP address it wants. - */ - if (!auth_ip_addr(f->unit, ho->hisaddr)) { - syslog(LOG_ERR, "Peer is not authorized to use remote address %s", - ip_ntoa(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) { - if (go->ouraddr != wo->ouraddr) - syslog(LOG_WARNING, "Local IP address changed to %s", - ip_ntoa(go->ouraddr)); - if (ho->hisaddr != wo->hisaddr) - syslog(LOG_WARNING, "Remote IP address changed to %s", - ip_ntoa(ho->hisaddr)); - ipcp_clear_addrs(f->unit); - - /* Set the interface to the new addresses */ - mask = GetMask(go->ouraddr); - if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { - IPCPDEBUG((LOG_WARNING, "sifaddr 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)) - default_route_set[f->unit] = 1; - - /* Make a proxy ARP entry if requested. */ - if (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)) { - IPCPDEBUG((LOG_WARNING, "sifaddr failed")); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } -#endif - - /* bring the interface up for IP */ - if (!sifup(f->unit)) { - IPCPDEBUG((LOG_WARNING, "sifup failed")); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } - -#if (defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { - IPCPDEBUG((LOG_WARNING, "sifaddr 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)) - default_route_set[f->unit] = 1; - - /* Make a proxy ARP entry if requested. */ - if (ipcp_wantoptions[f->unit].proxy_arp) - if (sifproxyarp(f->unit, ho->hisaddr)) - proxy_arp_set[f->unit] = 1; - - syslog(LOG_NOTICE, "local IP address %s", ip_ntoa(go->ouraddr)); - syslog(LOG_NOTICE, "remote IP address %s", ip_ntoa(ho->hisaddr)); - } - - /* - * Execute the ip-up script, like this: - * /etc/ppp/ip-up interface tty speed local-IP remote-IP - */ - ipcp_script(f, _PATH_IPUP); - -} - - -/* - * 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((LOG_INFO, "ipcp: down")); - np_down(f->unit, PPP_IP); - sifvjcomp(f->unit, 0, 0, 0); - - /* - * 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 { - sifdown(f->unit); - ipcp_clear_addrs(f->unit); - } - - /* Execute the ip-down script */ - ipcp_script(f, _PATH_IPDOWN); -} - - -/* - * ipcp_clear_addrs() - clear the interface addresses, routes, - * proxy arp entries, etc. - */ -static void -ipcp_clear_addrs(int unit) -{ - u_int32_t ouraddr, hisaddr; - - ouraddr = ipcp_gotoptions[unit].ouraddr; - hisaddr = ipcp_hisoptions[unit].hisaddr; - if (proxy_arp_set[unit]) { - cifproxyarp(unit, hisaddr); - proxy_arp_set[unit] = 0; - } - if (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) -{ - np_finished(f->unit, PPP_IP); -} - - -/* - * ipcp_script - Execute a script with arguments - * interface-name tty-name speed local-IP remote-IP. - */ -static void -ipcp_script(fsm *f, char *script) -{ - char strspeed[32], strlocal[32], strremote[32]; - char *argv[8]; - - sprintf(strspeed, "%d", baud_rate); - strcpy(strlocal, ip_ntoa(ipcp_gotoptions[f->unit].ouraddr)); - strcpy(strremote, ip_ntoa(ipcp_hisoptions[f->unit].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; - run_program(script, argv, 0); -} - -/* - * 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 %I", 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(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 -#define IPPROTO_TCP 6 -#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; -} diff --git a/usr.sbin/pppd/ipcp.h b/usr.sbin/pppd/ipcp.h deleted file mode 100644 index 62f75b8e98..0000000000 --- a/usr.sbin/pppd/ipcp.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * ipcp.h - IP Control Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/ipcp.h,v 1.10 1999/08/28 01:19:03 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/ipcp.h,v 1.3 2003/11/03 19:31:40 eirikn Exp $ - */ - -/* - * 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 { - int neg_addr : 1; /* Negotiate IP Address? */ - int old_addrs : 1; /* Use old (IP-Addresses) option? */ - int req_addr : 1; /* Ask peer to send IP address? */ - int default_route : 1; /* Assign default route through interface? */ - int proxy_arp : 1; /* Make proxy ARP entry for peer? */ - int neg_vj : 1; /* Van Jacobson Compression? */ - int old_vj : 1; /* use old (short) form of VJ option? */ - int accept_local : 1; /* accept peer's value for ouraddr */ - int accept_remote : 1; /* accept peer's value for hisaddr */ - u_short vj_protocol; /* protocol value to use in VJ option */ - u_char maxslotindex, cflag; /* values for RFC1332 VJ compression neg. */ - u_int32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ - u_int32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ - u_int32_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(u_int32_t); - -extern struct protent ipcp_protent; diff --git a/usr.sbin/pppd/lcp.c b/usr.sbin/pppd/lcp.c deleted file mode 100644 index feeb662c0d..0000000000 --- a/usr.sbin/pppd/lcp.c +++ /dev/null @@ -1,1809 +0,0 @@ -/* - * lcp.c - PPP Link Control Protocol. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/lcp.c,v 1.9.2.1 2003/04/22 10:27:44 fjoe Exp $ - * $DragonFly: src/usr.sbin/pppd/lcp.c,v 1.4 2005/11/24 23:42:54 swildner Exp $ - */ - -/* - * TODO: - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pppd.h" -#include "fsm.h" -#include "lcp.h" -#include "chap.h" -#include "magic.h" - -/* 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 */ -u_int32_t xmit_accm[NUM_PPP][8]; /* extended transmit ACCM */ - -static u_int32_t lcp_echos_pending = 0; /* Number of outstanding echo msgs */ -static u_int32_t lcp_echo_number = 0; /* ID number of next echo frame */ -static u_int32_t lcp_echo_timer_running = 0; /* TRUE 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); /* 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, - 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 + sizeof(short) */ -#define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */ -#define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */ -#define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */ -#define CILEN_CBCP 3 - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - - -/* - * 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); - - wo->passive = 0; - wo->silent = 0; - wo->restart = 0; /* Set to 1 in kernels or multi-line - implementations */ - wo->neg_mru = 1; - wo->mru = DEFMRU; - wo->neg_asyncmap = 0; - wo->asyncmap = 0; - wo->neg_chap = 0; /* Set to 1 on server */ - wo->neg_upap = 0; /* Set to 1 on server */ - wo->chap_mdtype = CHAP_DIGEST_MD5; - wo->neg_magicnumber = 1; - wo->neg_pcompression = 1; - wo->neg_accompression = 1; - wo->neg_lqr = 0; /* no LQR implementation yet */ - wo->neg_cbcp = 0; - - ao->neg_mru = 1; - ao->mru = MAXMRU; - ao->neg_asyncmap = 1; - ao->asyncmap = 0; - ao->neg_chap = 1; - ao->chap_mdtype = CHAP_DIGEST_MD5; - ao->neg_upap = 1; - ao->neg_magicnumber = 1; - ao->neg_pcompression = 1; - ao->neg_accompression = 1; - ao->neg_lqr = 0; /* no LQR implementation yet */ -#ifdef CBCP_SUPPORT - ao->neg_cbcp = 1; -#else - ao->neg_cbcp = 0; -#endif - - memset(xmit_accm[unit], 0, sizeof(xmit_accm[0])); - xmit_accm[unit][3] = 0x60000000; -} - - -/* - * 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 = 0; - 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]; - - if (phase != PHASE_DEAD) - phase = PHASE_TERMINATE; - if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) { - /* - * 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() in passive/silent mode when a connection hasn't - * been established. - */ - f->state = CLOSED; - lcp_finished(f); - - } else - fsm_close(&lcp_fsm[unit], reason); -} - - -/* - * lcp_lowerup - The lower layer is up. - */ -void -lcp_lowerup(int unit) -{ - lcp_options *wo = &lcp_wantoptions[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. - */ - ppp_set_xaccm(unit, xmit_accm[unit]); - ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0); - ppp_recv_config(unit, PPP_MRU, 0xffffffff, - wo->neg_pcompression, wo->neg_accompression); - peer_mru[unit] = PPP_MRU; - lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0]; - - fsm_lowerup(&lcp_fsm[unit]); -} - - -/* - * lcp_lowerdown - The lower layer is down. - */ -void -lcp_lowerdown(int unit) -{ - fsm_lowerdown(&lcp_fsm[unit]); -} - - -/* - * lcp_input - Input LCP packet. - */ -static void -lcp_input(int unit, u_char *p, int len) -{ - fsm *f = &lcp_fsm[unit]; - - 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; - LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d", id)); - 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: - 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; - - LCPDEBUG((LOG_INFO, "lcp_rprotrej.")); - - if (len < sizeof (u_short)) { - LCPDEBUG((LOG_INFO, - "lcp_rprotrej: Rcvd short Protocol-Reject packet!")); - return; - } - - GETSHORT(prot, inp); - - LCPDEBUG((LOG_INFO, - "lcp_rprotrej: Rcvd Protocol-Reject packet for %x!", - prot)); - - /* - * Protocol-Reject packets received in any state other than the LCP - * OPENED state SHOULD be silently discarded. - */ - if( f->state != OPENED ){ - LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d", - f->state)); - return; - } - - /* - * Upcall the proper Protocol-Reject routine. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol == prot && protp->enabled_flag) { - (*protp->protrej)(f->unit); - return; - } - - syslog(LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%x", - prot); -} - - -/* - * lcp_protrej - A Protocol-Reject was received. - */ -/*ARGSUSED*/ -static void -lcp_protrej(int unit) -{ - /* - * Can't reject LCP! - */ - LCPDEBUG((LOG_WARNING, - "lcp_protrej: 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_wantoptions[f->unit].magicnumber = magic(); - lcp_wantoptions[f->unit].numloops = 0; - lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit]; - 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 and UPAP, even if we will - * accept either. - */ - return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) + - LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) + - LENCICHAP(go->neg_chap) + - LENCISHORT(!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)); -} - - -/* - * 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, digest) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAP, ucp); \ - PUTSHORT(val, ucp); \ - PUTCHAR(digest, 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); \ - } - - ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); - ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, - go->asyncmap); - ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); - ADDCISHORT(CI_AUTHTYPE, !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); - - if (ucp - start_ucp != *lenp) { - /* this should never happen, because peer_mtu should be 1500 */ - syslog(LOG_ERR, "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, digest) \ - 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 != val) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != digest) \ - 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; \ - } - - ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); - ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, - go->asyncmap); - ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); - ACKCISHORT(CI_AUTHTYPE, !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); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - return (1); -bad: - LCPDEBUG((LOG_WARNING, "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) -{ - 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, code) \ - if (go->neg && \ - len >= CILEN_VOID && \ - p[1] == CILEN_VOID && \ - p[0] == opt) { \ - len -= CILEN_VOID; \ - INCPTR(CILEN_VOID, p); \ - no.neg = 1; \ - code \ - } -#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 \ - } - - /* - * 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) - && 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; - INCPTR(2, p); - GETSHORT(cishort, p); - if (cishort == PPP_PAP && cilen == CILEN_SHORT) { - /* - * If we were asking for CHAP, they obviously don't want to do it. - * If we weren't asking for CHAP, then we were asking for PAP, - * in which case this Nak is bad. - */ - if (!go->neg_chap) - goto bad; - try.neg_chap = 0; - - } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { - GETCHAR(cichar, p); - if (go->neg_chap) { - /* - * We were asking for CHAP/MD5; they must want a different - * algorithm. If they can't do MD5, we'll have to stop - * asking for CHAP. - */ - if (cichar != go->chap_mdtype) - try.neg_chap = 0; - } else { - /* - * Stop asking for PAP if we were asking for it. - */ - try.neg_upap = 0; - } - - } else { - /* - * We don't recognize what they're suggesting. - * Stop asking for what we were asking for. - */ - 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, - try.neg_pcompression = 0; - ); - NAKCIVOID(CI_ACCOMPRESSION, neg_accompression, - try.neg_accompression = 0; - ); - - /* - * 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.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) - 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; - } - 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) { - if (looped_back) { - if (++try.numloops >= lcp_loopbackfail) { - syslog(LOG_NOTICE, "Serial line is looped back."); - lcp_close(f->unit, "Loopback detected"); - } - } else - try.numloops = 0; - *go = try; - } - - return 1; - -bad: - LCPDEBUG((LOG_WARNING, "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; \ - LCPDEBUG((LOG_INFO, "lcp_rejci rejected void opt %d", opt)); \ - } -#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; \ - LCPDEBUG((LOG_INFO,"lcp_rejci rejected short opt %d", opt)); \ - } -#define REJCICHAP(opt, neg, val, digest) \ - 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 != val || cichar != digest) \ - goto bad; \ - try.neg = 0; \ - try.neg_upap = 0; \ - LCPDEBUG((LOG_INFO,"lcp_rejci rejected chap opt %d", opt)); \ - } -#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; \ - LCPDEBUG((LOG_INFO,"lcp_rejci rejected long opt %d", opt)); \ - } -#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; \ - LCPDEBUG((LOG_INFO,"lcp_rejci rejected LQR opt %d", opt)); \ - } -#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; \ - LCPDEBUG((LOG_INFO,"lcp_rejci rejected Callback opt %d", opt)); \ - } - - REJCISHORT(CI_MRU, neg_mru, go->mru); - REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); - REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_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); - - /* - * 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((LOG_WARNING, "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. - * - * Parameters: - * inp: Requested CIs - * len: Length of requested CIs - */ -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((LOG_WARNING, "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: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MRU")); - if (!ao->neg_mru || /* Allow option? */ - cilen != CILEN_SHORT) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETSHORT(cishort, p); /* Parse MRU */ - LCPDEBUG((LOG_INFO, "(%d)", cishort)); - - /* - * 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: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ASYNCMAP")); - if (!ao->neg_asyncmap || - cilen != CILEN_LONG) { - orc = CONFREJ; - break; - } - GETLONG(cilong, p); - LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong)); - - /* - * 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: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd AUTHTYPE")); - if (cilen < CILEN_SHORT || - !(ao->neg_upap || ao->neg_chap)) { - /* - * Reject the option if we're not willing to authenticate. - */ - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - LCPDEBUG((LOG_INFO, "(%x)", cishort)); - - /* - * Authtype must be UPAP or CHAP. - * - * Note: if both ao->neg_upap and ao->neg_chap are set, - * and the peer sends a Configure-Request with two - * authenticate-protocol requests, one for CHAP and one - * for UPAP, then we will reject the second request. - * Whether we end up doing CHAP or UPAP depends then on - * the ordering of the CIs in the peer's Configure-Request. - */ - - if (cishort == PPP_PAP) { - if (ho->neg_chap || /* we've already accepted CHAP */ - cilen != CILEN_SHORT) { - LCPDEBUG((LOG_WARNING, - "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 */ - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - break; - } - ho->neg_upap = 1; - break; - } - if (cishort == PPP_CHAP) { - if (ho->neg_upap || /* we've already accepted PAP */ - cilen != CILEN_CHAP) { - LCPDEBUG((LOG_INFO, - "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 PAP */ - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_PAP, nakp); - break; - } - GETCHAR(cichar, p); /* get digest type*/ - if (cichar != CHAP_DIGEST_MD5 -#ifdef CHAPMS - && cichar != CHAP_MICROSOFT -#endif - ) { - orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - break; - } - ho->chap_mdtype = cichar; /* save md type */ - ho->neg_chap = 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.) - */ - orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakp); - if (ao->neg_chap) { - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - } else { - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_PAP, nakp); - } - break; - - case CI_QUALITY: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd QUALITY")); - if (!ao->neg_lqr || - cilen != CILEN_LQR) { - orc = CONFREJ; - break; - } - - GETSHORT(cishort, p); - GETLONG(cilong, p); - LCPDEBUG((LOG_INFO, "(%x %x)", cishort, (unsigned int) cilong)); - - /* - * 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: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MAGICNUMBER")); - if (!(ao->neg_magicnumber || go->neg_magicnumber) || - cilen != CILEN_LONG) { - orc = CONFREJ; - break; - } - GETLONG(cilong, p); - LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong)); - - /* - * 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: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd PCOMPRESSION")); - if (!ao->neg_pcompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_pcompression = 1; - break; - - case CI_ACCOMPRESSION: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ACCOMPRESSION")); - if (!ao->neg_accompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_accompression = 1; - break; - - default: - LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd unknown option %d", - citype)); - orc = CONFREJ; - break; - } - -endswitch: - LCPDEBUG((LOG_INFO, " (%s)", 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? */ - && 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((LOG_INFO, "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]; - - 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. - */ - ppp_send_config(f->unit, MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)), - (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), - ho->neg_pcompression, ho->neg_accompression); - ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU), - (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" -}; - -static int -lcp_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(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"); - 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 "); - GETSHORT(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; - } - 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(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); - p += 4; - len -= 4; - } - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} - -/* - * Time to shut down the link because there is nothing out there. - */ - -static -void LcpLinkFailure(fsm *f) -{ - if (f->state == OPENED) { - syslog(LOG_INFO, "No response to %d echo-requests", lcp_echos_pending); - syslog(LOG_NOTICE, "Serial link appears to be disconnected."); - 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. - */ - assert (lcp_echo_timer_running==0); - 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) { - syslog(LOG_DEBUG, "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) { - syslog(LOG_WARNING, "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; - } - } - - /* - * 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; - } -} diff --git a/usr.sbin/pppd/lcp.h b/usr.sbin/pppd/lcp.h deleted file mode 100644 index 170ae3379e..0000000000 --- a/usr.sbin/pppd/lcp.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * lcp.h - Link Control Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/lcp.h,v 1.7 1999/08/28 01:19:05 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/lcp.h,v 1.3 2003/11/03 19:31:40 eirikn Exp $ - */ - -/* - * Options. - */ -#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_CALLBACK 13 /* callback */ - -/* - * LCP-specific packet types. - */ -#define PROTREJ 8 /* Protocol Reject */ -#define ECHOREQ 9 /* Echo Request */ -#define ECHOREP 10 /* Echo Reply */ -#define DISCREQ 11 /* Discard Request */ -#define CBCP_OPT 6 /* Use callback control protocol */ - -/* - * The state of options is described by an lcp_options structure. - */ -typedef struct lcp_options { - int passive : 1; /* Don't die if we don't get a response */ - int silent : 1; /* Wait for the other end to start first */ - int restart : 1; /* Restart vs. exit after close */ - int neg_mru : 1; /* Negotiate the MRU? */ - int neg_asyncmap : 1; /* Negotiate the async map? */ - int neg_upap : 1; /* Ask for UPAP authentication? */ - int neg_chap : 1; /* Ask for CHAP authentication? */ - int neg_magicnumber : 1; /* Ask for magic number? */ - int neg_pcompression : 1; /* HDLC Protocol Field Compression? */ - int neg_accompression : 1; /* HDLC Address/Control Field Compression? */ - int neg_lqr : 1; /* Negotiate use of Link Quality Reports */ - int neg_cbcp : 1; /* Negotiate use of CBCP */ - u_short mru; /* Value of MRU */ - u_char chap_mdtype; /* which MD type (hashing algorithm) */ - u_int32_t asyncmap; /* Value of async map */ - u_int32_t magicnumber; - int numloops; /* Number of loops during magic number neg. */ - u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */ -} 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[]; -extern u_int32_t xmit_accm[][8]; - -#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, u_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 diff --git a/usr.sbin/pppd/magic.c b/usr.sbin/pppd/magic.c deleted file mode 100644 index 316ce06094..0000000000 --- a/usr.sbin/pppd/magic.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * magic.c - PPP Magic Number routines. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/magic.c,v 1.8 1999/08/28 01:19:05 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/magic.c,v 1.4 2005/11/24 23:42:54 swildner Exp $ - */ - -#include -#include -#include -#include - -#include "pppd.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(); -} - -#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 diff --git a/usr.sbin/pppd/magic.h b/usr.sbin/pppd/magic.h deleted file mode 100644 index 3162c81105..0000000000 --- a/usr.sbin/pppd/magic.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * magic.h - PPP Magic Number definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/magic.h,v 1.7 1999/08/28 01:19:05 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/magic.h,v 1.3 2003/11/03 19:31:40 eirikn Exp $ - */ - -void magic_init(void); /* Initialize the magic number generator */ -u_int32_t magic(void); /* Returns the next magic number */ diff --git a/usr.sbin/pppd/main.c b/usr.sbin/pppd/main.c deleted file mode 100644 index 2446bcc66e..0000000000 --- a/usr.sbin/pppd/main.c +++ /dev/null @@ -1,1670 +0,0 @@ -/* - * main.c - Point-to-Point Protocol main module - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/main.c,v 1.19.2.1 2002/07/30 03:50:40 peter Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pppd.h" -#include "magic.h" -#include "fsm.h" -#include "lcp.h" -#include "ipcp.h" -#include "upap.h" -#include "chap.h" -#include "ccp.h" -#include "pathnames.h" -#include "patchlevel.h" - -#ifdef CBCP_SUPPORT -#include "cbcp.h" -#endif - -#if defined(SUNOS4) -extern char *strerror(); -#endif - -#ifdef IPX_CHANGE -#include "ipxcp.h" -#endif /* IPX_CHANGE */ -#ifdef AT_CHANGE -#include "atcp.h" -#endif - -/* interface vars */ -char ifname[32]; /* Interface name */ -int ifunit; /* Interface unit number */ - -char *progname; /* Name of this program */ -char hostname[MAXNAMELEN]; /* Our hostname */ -static char pidfilename[MAXPATHLEN]; /* name of pid file */ -static char iffilename[MAXPATHLEN]; /* name of if file */ -static char default_devnam[MAXPATHLEN]; /* name of default device */ -static pid_t pid; /* Our pid */ -static uid_t uid; /* Our real user-id */ -time_t etime,stime; /* End and Start time */ -int minutes; /* connection duration */ -static int conn_running; /* we have a [dis]connector running */ - -int ttyfd = -1; /* Serial port file descriptor */ -mode_t tty_mode = -1; /* Original access permissions to tty */ -int baud_rate; /* Actual bits/second for serial device */ -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 */ - -int phase; /* where the link is at */ -int kill_link; -int open_ccp_flag; - -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 locked; /* lock() has succeeded */ - -char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; - -/* Prototypes for procedures local to this file. */ - -static void create_pidfile(void); -static void cleanup(void); -static void close_tty(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 int device_script(char *, int, int); -static void reap_kids(void); -static void pr_log(void *, char *, ...); - -extern char *ttyname(int); -extern char *getlogin(void); - -#ifdef ultrix -#undef O_NONBLOCK -#define O_NONBLOCK O_NDELAY -#endif - -#ifdef ULTRIX -#define setlogmask(x) -#endif - -/* - * 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 CBCP_SUPPORT - &cbcp_protent, -#endif - &ipcp_protent, - &ccp_protent, -#ifdef IPX_CHANGE - &ipxcp_protent, -#endif -#ifdef AT_CHANGE - &atcp_protent, -#endif - NULL -}; - -int -main(int argc, char *argv[]) -{ - int i, n, fdflags; - struct sigaction sa; - FILE *iffile; - char *p; - struct passwd *pw; - struct timeval timo; - sigset_t mask; - struct protent *protp; - struct stat statbuf; - int connect_attempts = 0; - char numbuf[16]; - - phase = PHASE_INITIALIZE; - p = ttyname(0); - if (p) - strcpy(devnam, p); - strcpy(default_devnam, devnam); - - script_env = NULL; - - /* Initialize syslog facilities */ -#ifdef ULTRIX - openlog("pppd", LOG_PID); -#else - openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); - setlogmask(LOG_UPTO(LOG_INFO)); -#endif - - if (gethostname(hostname, MAXNAMELEN) < 0 ) { - option_error("Couldn't get hostname: %m"); - die(1); - } - hostname[MAXNAMELEN-1] = 0; - - uid = getuid(); - privileged = uid == 0; - sprintf(numbuf, "%d", uid); - script_setenv("UID", numbuf); - - /* - * Initialize to the standard option set, then parse, in order, - * the system options file, the user's options file, - * the tty's options file, and the command line arguments. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - (*protp->init)(0); - - progname = *argv; - - if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1) - || !options_from_user()) - exit(1); - scan_args(argc-1, argv+1); /* look for tty name on command line */ - if (!options_for_tty() - || !parse_args(argc-1, argv+1)) - exit(1); - - /* - * Check that we are running as root. - */ - if (geteuid() != 0) { - option_error("must be root to run %s, since it is not setuid-root", - argv[0]); - die(1); - } - - if (!ppp_available()) { - option_error(no_ppp_msg); - exit(1); - } - - /* - * Check that the options given are valid and consistent. - */ - sys_check_options(); - auth_check_options(); - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->check_options != NULL) - (*protp->check_options)(); - if (demand && connector == 0) { - option_error("connect script required for demand-dialling\n"); - exit(1); - } - - script_setenv("DEVICE", devnam); - sprintf(numbuf, "%d", baud_rate); - script_setenv("SPEED", numbuf); - - /* - * If the user has specified the default device name explicitly, - * pretend they hadn't. - */ - if (!default_device && strcmp(devnam, default_devnam) == 0) - default_device = 1; - if (default_device) - nodetach = 1; - - /* - * Initialize system-dependent stuff and magic number package. - */ - sys_init(); - magic_init(); - if (debug) - setlogmask(LOG_UPTO(LOG_DEBUG)); - - /* - * Detach ourselves from the terminal, if required, - * and identify who is running us. - */ - if (nodetach == 0) - detach(); - pid = getpid(); - p = getlogin(); - stime = time(NULL); - 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.%d%s started by %s, uid %d", - VERSION, PATCHLEVEL, IMPLEMENTATION, p, uid); - - /* - * 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(&mask); - sigaddset(&mask, SIGHUP); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGTERM); - sigaddset(&mask, SIGCHLD); - -#define SIGNAL(s, handler) { \ - sa.sa_handler = handler; \ - if (sigaction(s, &sa, NULL) < 0) { \ - syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \ - die(1); \ - } \ - } - - sa.sa_mask = mask; - 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); - - /* - * 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. - */ - open_ppp_loopback(); - - syslog(LOG_INFO, "Using interface ppp%d", ifunit); - sprintf(ifname, "ppp%d", ifunit); - script_setenv("IFNAME", ifname); - - create_pidfile(); /* write pid to file */ - - /* - * Configure the interface and mark it up, etc. - */ - demand_conf(); - } - - for (;;) { - - need_holdoff = 1; - - if (demand) { - /* - * Don't do anything until we see some activity. - */ - phase = PHASE_DORMANT; - kill_link = 0; - demand_unblock(); - for (;;) { - wait_loop_output(timeleft(&timo)); - calltimeout(); - if (kill_link) { - if (!persist) - die(0); - kill_link = 0; - } - if (get_loop_output()) - break; - reap_kids(); - } - - /* - * Now we want to bring up the link. - */ - demand_block(); - syslog(LOG_INFO, "Starting link"); - } - - /* - * Lock the device if we've been asked to. - */ - if (lockflag && !default_device) { - if (lock(devnam) < 0) - goto fail; - 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. - */ - while ((ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0)) < 0) { - if (errno != EINTR) - syslog(LOG_ERR, "Failed to open %s: %m", devnam); - if (!persist || errno != EINTR) - goto fail; - } - if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 - || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) - syslog(LOG_WARNING, - "Couldn't reset non-blocking mode on device: %m"); - - hungup = 0; - kill_link = 0; - - /* - * 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) { - syslog(LOG_WARNING, - "Couldn't restrict write permissions to %s: %m", devnam); - } else - tty_mode = statbuf.st_mode; - - /* run connection script */ - if (connector && connector[0]) { - MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector)); - - /* - * Set line speed, flow control, etc. - * 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 can clear CLOCAL at this point. - */ - set_up_tty(ttyfd, 1); - - /* drop dtr to hang up in case modem is off hook */ - if (!default_device && modem) { - setdtr(ttyfd, FALSE); - sleep(1); - setdtr(ttyfd, TRUE); - } - - if (device_script(connector, ttyfd, ttyfd) < 0) { - syslog(LOG_ERR, "Connect script failed"); - setdtr(ttyfd, FALSE); - connect_attempts++; - goto fail; - } - - - syslog(LOG_INFO, "Serial connection established."); - sleep(1); /* give it time to set up its terminal */ - } - - connect_attempts = 0; /* we made it through ok */ - - /* set line speed, flow control, etc.; clear CLOCAL if modem option */ - set_up_tty(ttyfd, 0); - - /* reopen tty if necessary to wait for carrier */ - if (connector == NULL && modem) { - while ((i = open(devnam, O_RDWR)) < 0) { - if (errno != EINTR) - syslog(LOG_ERR, "Failed to reopen %s: %m", devnam); - if (!persist || errno != EINTR || - hungup || kill_link) - goto fail; - } - close(i); - } - - /* run welcome script, if any */ - if (welcomer && welcomer[0]) { - if (device_script(welcomer, ttyfd, ttyfd) < 0) - syslog(LOG_WARNING, "Welcome script failed"); - } - - /* set up the serial device as a ppp interface */ - establish_ppp(ttyfd); - - if (!demand) { - - syslog(LOG_INFO, "Using interface ppp%d", ifunit); - sprintf(ifname, "ppp%d", ifunit); - - create_pidfile(); /* write pid to file */ - - /* write interface unit number to file */ - for (n = strlen(devnam); n > 0 ; n--) - if (devnam[n] == '/') { - n++; - break; - } - sprintf(iffilename, "%s%s.if", _PATH_VARRUN, &devnam[n]); - if ((iffile = fopen(iffilename, "w")) != NULL) { - fprintf(iffile, "ppp%d\n", ifunit); - fclose(iffile); - } else { - syslog(LOG_ERR, "Failed to create if file %s: %m", iffilename); - iffilename[0] = 0; - } - - script_setenv("IFNAME", ifname); - } - - /* - * Start opening the connection and wait for - * incoming events (reply, timeout, etc.). - */ - syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam); - stime = time(NULL); - lcp_lowerup(0); - lcp_open(0); /* Start protocol */ - for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) { - wait_input(timeleft(&timo)); - calltimeout(); - get_input(); - if (kill_link) { - lcp_close(0, "User request"); - kill_link = 0; - } - if (open_ccp_flag) { - if (phase == PHASE_NETWORK) { - ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ - (*ccp_protent.open)(0); - } - open_ccp_flag = 0; - } - reap_kids(); /* Don't leave dead kids lying around */ - } - - /* - * 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. - */ - clean_check(); - if (demand) - restore_loop(); - disestablish_ppp(ttyfd); - - /* - * Run disconnector script, if requested. - * XXX we may not be able to do this if the line has hung up! - */ - if (disconnector && !hungup) { - set_up_tty(ttyfd, 1); - if (device_script(disconnector, ttyfd, ttyfd) < 0) { - syslog(LOG_WARNING, "disconnect script failed"); - } else { - syslog(LOG_INFO, "Serial link disconnected."); - } - } - - fail: - if (ttyfd >= 0) - close_tty(); - if (locked) { - unlock(); - locked = 0; - } - - if (!demand) { - if (pidfilename[0] != 0 - && unlink(pidfilename) < 0 && errno != ENOENT) - syslog(LOG_WARNING, "unable to delete pid file: %m"); - pidfilename[0] = 0; - - if (iffile) - if (unlink(iffilename) < 0 && errno != ENOENT) - syslog(LOG_WARNING, "unable to delete if file: %m"); - iffilename[0] = 0; - } - - /* limit to retries? */ - if (max_con_attempts) - if (connect_attempts >= max_con_attempts) - break; - - if (!persist) - die(1); - - if (demand) - demand_discard(); - if (holdoff > 0 && need_holdoff) { - phase = PHASE_HOLDOFF; - TIMEOUT(holdoff_end, NULL, holdoff); - do { - wait_time(timeleft(&timo)); - calltimeout(); - if (kill_link) { - if (!persist) - die(0); - kill_link = 0; - phase = PHASE_DORMANT; /* allow signal to end holdoff */ - } - reap_kids(); - } while (phase == PHASE_HOLDOFF); - } - } - - die(0); - return 0; -} - -/* - * detach - detach us from the controlling terminal. - */ -void -detach(void) -{ - if (detached) - return; - if (daemon(0, 0) < 0) { - perror("Couldn't detach from controlling terminal"); - die(1); - } - detached = 1; - pid = getpid(); - /* update pid file if it has been written already */ - if (pidfilename[0]) - create_pidfile(); -} - -/* - * Create a file containing our process ID. - */ -static void -create_pidfile(void) -{ - FILE *pidfile; - - sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname); - if ((pidfile = fopen(pidfilename, "w")) != NULL) { - fprintf(pidfile, "%d\n", pid); - fclose(pidfile); - } else { - syslog(LOG_ERR, "Failed to create pid file %s: %m", pidfilename); - pidfilename[0] = 0; - } -} - -/* - * holdoff_end - called via a timeout when the holdoff period ends. - */ -static void -holdoff_end(void *arg) -{ - phase = PHASE_DORMANT; -} - -/* - * 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) { - etime = time(NULL); - minutes = (etime-stime)/60; - syslog(LOG_NOTICE, "Modem hangup, connected for %d minutes", (minutes >1) ? minutes : 1); - hungup = 1; - lcp_lowerdown(0); /* serial link is no longer available */ - link_terminated(0); - return; - } - - if (debug /*&& (debugflags & DBG_INPACKET)*/) - log_packet(p, len, "rcvd ", LOG_DEBUG); - - if (len < PPP_HDRLEN) { - MAINDEBUG((LOG_INFO, "io(): Received short packet.")); - return; - } - - 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) { - MAINDEBUG((LOG_INFO, - "get_input: Received 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)) { - MAINDEBUG((LOG_INFO, "get_input: 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) - syslog(LOG_WARNING, "Unsupported protocol (0x%x) received", protocol); - lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); -} - - -/* - * quit - Clean up state and exit (with an error indication). - */ -void -quit(void) -{ - die(1); -} - -/* - * die - like quit, except we can specify an exit status. - */ -void -die(int status) -{ - cleanup(); - 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 (ttyfd >= 0) - close_tty(); - - if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) - syslog(LOG_WARNING, "unable to delete pid file: %m"); - pidfilename[0] = 0; - - if (locked) - unlock(); -} - -/* - * close_tty - restore the terminal device and close it. - */ -static void -close_tty(void) -{ - disestablish_ppp(ttyfd); - - /* drop dtr to hang up */ - if (modem) { - setdtr(ttyfd, FALSE); - /* - * 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(ttyfd); - - if (tty_mode != (mode_t) -1) - fchmod(ttyfd, tty_mode); - - close(ttyfd); - ttyfd = -1; -} - - -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. - * - * Note that this timeout takes the number of seconds, NOT hz (as in - * the kernel). - */ -void -timeout(void (*func)(void *), void *arg, int time) -{ - struct callout *newp, *p, **pp; - - MAINDEBUG((LOG_DEBUG, "Timeout %lx:%lx in %d seconds.", - (long) func, (long) arg, time)); - - /* - * Allocate timeout. - */ - if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) { - syslog(LOG_ERR, "Out of memory in timeout()!"); - die(1); - } - newp->c_arg = arg; - newp->c_func = func; - gettimeofday(&timenow, NULL); - newp->c_time.tv_sec = timenow.tv_sec + time; - newp->c_time.tv_usec = timenow.tv_usec; - - /* - * 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_sec)) - break; - newp->c_next = p; - *pp = newp; -} - - -/* - * untimeout - Unschedule a timeout. - */ -void -untimeout(void (*func)(void *), void *arg) -{ - struct callout **copp, *freep; - - MAINDEBUG((LOG_DEBUG, "Untimeout %lx:%lx.", (long) func, (long) arg)); - - /* - * 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 (gettimeofday(&timenow, NULL) < 0) { - syslog(LOG_ERR, "Failed to get time of day: %m"); - die(1); - } - 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; - - gettimeofday(&timenow, NULL); - 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. - */ -static void -kill_my_pg(int sig) -{ - struct sigaction act, oldact; - - act.sa_handler = SIG_IGN; - act.sa_flags = 0; - kill(0, sig); - 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) -{ - syslog(LOG_INFO, "Hangup (SIGHUP)"); - kill_link = 1; - if (conn_running) - /* Send the signal to the [dis]connector process(es) also */ - kill_my_pg(sig); -} - - -/* - * 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) -{ - syslog(LOG_INFO, "Terminating on signal %d.", sig); - persist = 0; /* don't try to restart */ - kill_link = 1; - if (conn_running) - /* Send the signal to the [dis]connector process(es) also */ - kill_my_pg(sig); -} - - -/* - * chld - Catch SIGCHLD signal. - * Calls reap_kids to get status for any dead kids. - */ -static void -chld(int sig) -{ - reap_kids(); -} - - -/* - * 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) -{ - open_ccp_flag = 1; -} - - -/* - * 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; - syslog(LOG_ERR, "Fatal signal %d", sig); - if (conn_running) - kill_my_pg(SIGTERM); - die(1); -} - - -/* - * device_script - run a program to connect or disconnect the - * serial device. - */ -static int -device_script(char *program, int in, int out) -{ - int pid; - int status; - int errfd; - - conn_running = 1; - pid = fork(); - - if (pid < 0) { - conn_running = 0; - syslog(LOG_ERR, "Failed to create child process: %m"); - die(1); - } - - if (pid == 0) { - sys_close(); - closelog(); - if (in == out) { - if (in != 0) { - dup2(in, 0); - close(in); - } - dup2(0, 1); - } else { - if (out == 0) - out = dup(out); - if (in != 0) { - dup2(in, 0); - close(in); - } - if (out != 1) { - dup2(out, 1); - close(out); - } - } - if (nodetach == 0) { - close(2); - errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); - if (errfd >= 0 && errfd != 2) { - dup2(errfd, 2); - close(errfd); - } - } - setuid(getuid()); - setgid(getgid()); - execl("/bin/sh", "sh", "-c", program, NULL); - syslog(LOG_ERR, "could not exec /bin/sh: %m"); - _exit(99); - /* NOTREACHED */ - } - - while (waitpid(pid, &status, 0) < 0) { - if (errno == EINTR) - continue; - syslog(LOG_ERR, "error waiting for (dis)connection process: %m"); - die(1); - } - conn_running = 0; - - return (status == 0 ? 0 : -1); -} - - -/* - * run-program - execute a program with given arguments, - * but don't wait for it. - * If the program can't be executed, logs an error unless - * must_exist is 0 and the program file doesn't exist. - */ -int -run_program(char *prog, char **args, int must_exist) -{ - int pid; - - pid = fork(); - if (pid == -1) { - syslog(LOG_ERR, "Failed to create child process for %s: %m", prog); - return -1; - } - if (pid == 0) { - int new_fd; - - /* Leave the current location */ - setsid(); /* No controlling tty. */ - umask (S_IRWXG|S_IRWXO); - chdir ("/"); /* no current directory. */ - setuid(geteuid()); - setgid(getegid()); - - /* Ensure that nothing of our device environment is inherited. */ - sys_close(); - closelog(); - close (0); - close (1); - close (2); - close (ttyfd); /* tty interface to the ppp device */ - - /* Don't pass handles to the PPP device, even by accident. */ - new_fd = open (_PATH_DEVNULL, O_RDWR); - if (new_fd >= 0) { - if (new_fd != 0) { - dup2 (new_fd, 0); /* stdin <- /dev/null */ - close (new_fd); - } - dup2 (0, 1); /* stdout -> /dev/null */ - dup2 (0, 2); /* stderr -> /dev/null */ - } - -#ifdef BSD - /* Force the priority back to zero if pppd is running higher. */ - if (setpriority (PRIO_PROCESS, 0, 0) < 0) - syslog (LOG_WARNING, "can't reset priority to 0: %m"); -#endif - - /* SysV recommends a second fork at this point. */ - - /* run the program; give it a null environment */ - execve(prog, args, script_env); - if (must_exist || errno != ENOENT) - syslog(LOG_WARNING, "Can't execute %s: %m", prog); - _exit(-1); - } - MAINDEBUG((LOG_DEBUG, "Script %s started; pid = %d", prog, pid)); - ++n_children; - return 0; -} - - -/* - * reap_kids - get status from any dead child processes, - * and log a message for abnormal terminations. - */ -static void -reap_kids(void) -{ - int pid, status; - - if (n_children == 0) - return; - if ((pid = waitpid(-1, &status, WNOHANG)) == -1) { - if (errno != ECHILD) - syslog(LOG_ERR, "Error waiting for child process: %m"); - return; - } - if (pid > 0) { - --n_children; - if (WIFSIGNALED(status)) { - syslog(LOG_WARNING, "Child process %d terminated with signal %d", - pid, WTERMSIG(status)); - } - } -} - - -/* - * log_packet - format a packet and log it. - */ - -char line[256]; /* line to be logged accumulated here */ -char *linep; - -void -log_packet(u_char *p, int len, char *prefix, int level) -{ - strcpy(line, prefix); - linep = line + strlen(line); - format_packet(p, len, pr_log, NULL); - if (linep != line) - syslog(level, "%s", line); -} - -/* - * format_packet - make a readable representation of a packet, - * calling `printer(arg, format, ...)' to output it. - */ -void -format_packet(u_char *p, int len, void (*printer)(void *, char *, ...), - void *arg) -{ - int i, n; - u_short proto; - u_char x; - 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 { - printer(arg, "[proto=0x%x]", proto); - } - } - - for (; len > 0; --len) { - GETCHAR(x, p); - printer(arg, " %.2x", x); - } -} - -static void -pr_log __V((void *arg, char *fmt, ...)) -{ - int n; - va_list pvar; - char buf[256]; - -#if __STDC__ - va_start(pvar, fmt); -#else - void *arg; - char *fmt; - va_start(pvar); - arg = va_arg(pvar, void *); - fmt = va_arg(pvar, char *); -#endif - - n = vfmtmsg(buf, sizeof(buf), fmt, pvar); - va_end(pvar); - - if (linep + n + 1 > line + sizeof(line)) { - syslog(LOG_DEBUG, "%s", line); - linep = line; - } - strcpy(linep, buf); - linep += n; -} - -/* - * print_string - print a readable representation of a string using - * printer. - */ -void -print_string(char *p, int len, void (*printer)(void *, char *, ...), - 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", c); - } - } - } - printer(arg, "\""); -} - -/* - * novm - log an error message saying we ran out of memory, and die. - */ -void -novm(char *msg) -{ - syslog(LOG_ERR, "Virtual memory exhausted allocating %s\n", msg); - die(1); -} - -/* - * fmtmsg - format a message into a buffer. Like sprintf except we - * also specify the length of the output buffer, and we handle - * %r (recursive format), %m (error message) and %I (IP address) formats. - * Doesn't do floating-point formats. - * Returns the number of chars put into buf. - */ -int -fmtmsg __V((char *buf, int buflen, char *fmt, ...)) -{ - va_list args; - int n; - -#if __STDC__ - va_start(args, fmt); -#else - char *buf; - int buflen; - char *fmt; - va_start(args); - buf = va_arg(args, char *); - buflen = va_arg(args, int); - fmt = va_arg(args, char *); -#endif - n = vfmtmsg(buf, buflen, fmt, args); - va_end(args); - return n; -} - -/* - * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args. - */ -#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) - -int -vfmtmsg(char *buf, int buflen, char *fmt, va_list args) -{ - int c, i, n; - int width, prec, fillch; - int base, len, neg, quoted; - unsigned long val = 0; - char *str, *f, *buf0; - unsigned char *p; - char num[32]; - time_t t; - 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 = NULL; - 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 'I': - str = ip_ntoa(va_arg(args, u_int32_t)); - break; - case 'r': - f = va_arg(args, char *); - n = vfmtmsg(buf, buflen + 1, f, va_arg(args, void *)); - buf += n; - buflen -= n; - continue; - 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 (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; -} - -/* - * script_setenv - set an environment variable value to be used - * for scripts that we run (e.g. ip-up, auth-up, etc.) - */ -void -script_setenv(char *var, char *value) -{ - int vl = strlen(var); - int i; - char *p, *newstring; - - newstring = (char *) malloc(vl + strlen(value) + 2); - if (newstring == NULL) - return; - strcpy(newstring, var); - newstring[vl] = '='; - strcpy(newstring+vl+1, value); - - /* check if this variable is already set */ - if (script_env != NULL) { - for (i = 0; (p = script_env[i]) != NULL; ++i) { - if (strncmp(p, var, vl) == 0 && p[vl] == '=') { - free(p); - script_env[i] = newstring; - return; - } - } - } else { - i = 0; - script_env = (char **) malloc(16 * sizeof(char *)); - if (script_env == NULL) - return; - s_env_nalloc = 16; - } - - /* reallocate script_env with more space if needed */ - if (i + 1 >= s_env_nalloc) { - int new_n = i + 17; - char **newenv = (char **) realloc((void *)script_env, - new_n * sizeof(char *)); - if (newenv == NULL) - return; - script_env = newenv; - s_env_nalloc = new_n; - } - - script_env[i] = newstring; - script_env[i+1] = NULL; -} - -/* - * script_unsetenv - remove a variable from the environment - * for scripts. - */ -void -script_unsetenv(char *var) -{ - int vl = strlen(var); - int i; - char *p; - - if (script_env == NULL) - return; - for (i = 0; (p = script_env[i]) != NULL; ++i) { - if (strncmp(p, var, vl) == 0 && p[vl] == '=') { - free(p); - while ((script_env[i] = script_env[i+1]) != NULL) - ++i; - break; - } - } -} diff --git a/usr.sbin/pppd/options.c b/usr.sbin/pppd/options.c deleted file mode 100644 index c730768ba0..0000000000 --- a/usr.sbin/pppd/options.c +++ /dev/null @@ -1,2438 +0,0 @@ -/* - * options.c - handles option processing for PPP. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/options.c,v 1.20.2.2 2002/08/31 18:16:01 dwmalone Exp $ - * $DragonFly: src/usr.sbin/pppd/options.c,v 1.6 2005/11/24 23:42:54 swildner Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef PPP_FILTER -#include -#include /* XXX: To get struct pcap */ -#endif - -#include "pppd.h" -#include "pathnames.h" -#include "patchlevel.h" -#include "fsm.h" -#include "lcp.h" -#include "ipcp.h" -#include "upap.h" -#include "chap.h" -#include "ccp.h" -#ifdef CBCP_SUPPORT -#include "cbcp.h" -#endif - -#ifdef IPX_CHANGE -#include "ipxcp.h" -#endif /* IPX_CHANGE */ - -#include - -#define FALSE 0 -#define TRUE 1 - -#if defined(ultrix) || defined(NeXT) -char *strdup(char *); -#endif - -#ifndef GIDSET_TYPE -#define GIDSET_TYPE gid_t -#endif - -/* - * Option variables and default values. - */ -#ifdef PPP_FILTER -int dflag = 0; /* Tell libpcap we want debugging */ -#endif -int debug = 0; /* Debug flag */ -int kdebugflag = 0; /* Tell kernel to print debug messages */ -int default_device = 1; /* Using /dev/tty or equivalent */ -char devnam[MAXPATHLEN] = _PATH_TTY; /* Device name */ -int crtscts = 0; /* Use hardware flow control */ -int modem = 1; /* Use modem control lines */ -int inspeed = 0; /* Input/Output speed requested */ -u_int32_t netmask = 0; /* IP netmask to set on interface */ -int lockflag = 0; /* Create lock file to lock the serial dev */ -int nodetach = 0; /* Don't detach from controlling tty */ -char *connector = NULL; /* Script to establish physical link */ -char *disconnector = NULL; /* Script to disestablish physical link */ -char *welcomer = NULL; /* Script to run after phys link estab. */ -int max_con_attempts = 0; /* Maximum connect tries in non-demand mode */ -int maxconnect = 0; /* Maximum connect time */ -char user[MAXNAMELEN]; /* Username for PAP */ -char passwd[MAXSECRETLEN]; /* Password for PAP */ -int auth_required = 0; /* Peer is required to authenticate */ -int defaultroute = 0; /* assign default route through interface */ -int proxyarp = 0; /* Set up proxy ARP entry for peer */ -int persist = 0; /* Reopen link after it goes down */ -int uselogin = 0; /* Use /etc/passwd for checking PAP */ -int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ -int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ -char our_name[MAXNAMELEN]; /* Our name for authentication purposes */ -char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ -int explicit_remote = 0; /* User specified explicit remote name */ -int usehostname = 0; /* Use hostname for our_name */ -int disable_defaultip = 0; /* Don't use hostname for default IP adrs */ -int demand = 0; /* do dial-on-demand */ -char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ -int cryptpap; /* Passwords in pap-secrets are encrypted */ -int idle_time_limit = 0; /* Disconnect if idle for this many seconds */ -int holdoff = 30; /* # seconds to pause before reconnecting */ -int refuse_pap = 0; /* Set to say we won't do PAP */ -int refuse_chap = 0; /* Set to say we won't do CHAP */ - -#ifdef MSLANMAN -int ms_lanman = 0; /* Nonzero if use LanMan password instead of NT */ - /* Has meaning only with MS-CHAP challenges */ -#endif - -struct option_info auth_req_info; -struct option_info connector_info; -struct option_info disconnector_info; -struct option_info welcomer_info; -struct option_info devnam_info; -#ifdef PPP_FILTER -struct bpf_program pass_filter;/* Filter program for packets to pass */ -struct bpf_program active_filter; /* Filter program for link-active pkts */ -pcap_t pc; /* Fake struct pcap so we can compile expr */ -#endif - -/* - * Prototypes - */ -static int setdevname(char *, int); -static int setspeed(char *); -static int setdebug(char **); -static int setkdebug(char **); -static int setpassive(char **); -static int setsilent(char **); -static int noopt(char **); -static int setnovj(char **); -static int setnovjccomp(char **); -static int setvjslots(char **); -static int reqpap(char **); -static int nopap(char **); -#ifdef OLD_OPTIONS -static int setupapfile(char **); -#endif -static int nochap(char **); -static int reqchap(char **); -static int noaccomp(char **); -static int noasyncmap(char **); -static int noip(char **); -static int nomagicnumber(char **); -static int setasyncmap(char **); -static int setescape(char **); -static int setmru(char **); -static int setmtu(char **); -#ifdef CBCP_SUPPORT -static int setcbcp(char **); -#endif -static int nomru(char **); -static int nopcomp(char **); -static int setconnector(char **); -static int setdisconnector(char **); -static int setwelcomer(char **); -static int setmaxcon(char **); -static int setmaxconnect(char **); -static int setdomain(char **); -static int setnetmask(char **); -static int setcrtscts(char **); -static int setnocrtscts(char **); -static int setxonxoff(char **); -static int setnodetach(char **); -static int setupdetach(char **); -static int setmodem(char **); -static int setlocal(char **); -static int setlock(char **); -static int setname(char **); -static int setuser(char **); -static int setremote(char **); -static int setauth(char **); -static int setnoauth(char **); -static int readfile(char **); -static int callfile(char **); -static int setdefaultroute(char **); -static int setnodefaultroute(char **); -static int setproxyarp(char **); -static int setnoproxyarp(char **); -static int setpersist(char **); -static int setnopersist(char **); -static int setdologin(char **); -static int setusehostname(char **); -static int setnoipdflt(char **); -static int setlcptimeout(char **); -static int setlcpterm(char **); -static int setlcpconf(char **); -static int setlcpfails(char **); -static int setipcptimeout(char **); -static int setipcpterm(char **); -static int setipcpconf(char **); -static int setipcpfails(char **); -static int setpaptimeout(char **); -static int setpapreqs(char **); -static int setpapreqtime(char **); -static int setchaptimeout(char **); -static int setchapchal(char **); -static int setchapintv(char **); -static int setipcpaccl(char **); -static int setipcpaccr(char **); -static int setlcpechointv(char **); -static int setlcpechofails(char **); -static int noccp(char **); -static int setbsdcomp(char **); -static int setnobsdcomp(char **); -static int setdeflate(char **); -static int setnodeflate(char **); -static int setnodeflatedraft(char **); -static int setdemand(char **); -static int setpred1comp(char **); -static int setnopred1comp(char **); -static int setipparam(char **); -static int setpapcrypt(char **); -static int setidle(char **); -static int setholdoff(char **); -static int setdnsaddr(char **); -static int resetipxproto(char **); -static int setwinsaddr(char **); -static int showversion(char **); -static int showhelp(char **); - -#ifdef PPP_FILTER -static int setpdebug(char **); -static int setpassfilter(char **); -static int setactivefilter(char **); -#endif - -#ifdef IPX_CHANGE -static int setipxproto(char **); -static int setipxanet(char **); -static int setipxalcl(char **); -static int setipxarmt(char **); -static int setipxnetwork(char **); -static int setipxnode(char **); -static int setipxrouter(char **); -static int setipxname(char **); -static int setipxcptimeout(char **); -static int setipxcpterm(char **); -static int setipxcpconf(char **); -static int setipxcpfails(char **); -#endif /* IPX_CHANGE */ - -#ifdef MSLANMAN -static int setmslanman(char **); -#endif - -static int number_option(char *, u_int32_t *, int); -static int int_option(char *, int *); -static int readable(int fd); - -/* - * Valid arguments. - */ -static struct cmd { - char *cmd_name; - int num_args; - int (*cmd_func)(char **); -} cmds[] = { - {"-all", 0, noopt}, /* Don't request/allow any options (useless) */ - {"noaccomp", 0, noaccomp}, /* Disable Address/Control compression */ - {"-ac", 0, noaccomp}, /* Disable Address/Control compress */ - {"default-asyncmap", 0, noasyncmap}, /* Disable asyncmap negoatiation */ - {"-am", 0, noasyncmap}, /* Disable asyncmap negotiation */ - {"-as", 1, setasyncmap}, /* set the desired async map */ - {"-d", 0, setdebug}, /* Increase debugging level */ - {"nodetach", 0, setnodetach}, /* Don't detach from controlling tty */ - {"-detach", 0, setnodetach}, /* don't fork */ - {"updetach", 0, setupdetach}, /* Detach once an NP has come up */ - {"noip", 0, noip}, /* Disable IP and IPCP */ - {"-ip", 0, noip}, /* Disable IP and IPCP */ - {"nomagic", 0, nomagicnumber}, /* Disable magic number negotiation */ - {"-mn", 0, nomagicnumber}, /* Disable magic number negotiation */ - {"default-mru", 0, nomru}, /* Disable MRU negotiation */ - {"-mru", 0, nomru}, /* Disable mru negotiation */ - {"-p", 0, setpassive}, /* Set passive mode */ - {"nopcomp", 0, nopcomp}, /* Disable protocol field compression */ - {"-pc", 0, nopcomp}, /* Disable protocol field compress */ -#if OLD_OPTIONS - {"+ua", 1, setupapfile}, /* Get PAP user and password from file */ -#endif - {"require-pap", 0, reqpap}, /* Require PAP authentication from peer */ - {"+pap", 0, reqpap}, /* Require PAP auth from peer */ - {"refuse-pap", 0, nopap}, /* Don't agree to auth to peer with PAP */ - {"-pap", 0, nopap}, /* Don't allow UPAP authentication with peer */ - {"require-chap", 0, reqchap}, /* Require CHAP authentication from peer */ - {"+chap", 0, reqchap}, /* Require CHAP authentication from peer */ - {"refuse-chap", 0, nochap}, /* Don't agree to auth to peer with CHAP */ - {"-chap", 0, nochap}, /* Don't allow CHAP authentication with peer */ - {"novj", 0, setnovj}, /* Disable VJ compression */ - {"-vj", 0, setnovj}, /* disable VJ compression */ - {"novjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */ - {"-vjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */ - {"vj-max-slots", 1, setvjslots}, /* Set maximum VJ header slots */ - {"asyncmap", 1, setasyncmap}, /* set the desired async map */ - {"escape", 1, setescape}, /* set chars to escape on transmission */ - {"connect", 1, setconnector}, /* A program to set up a connection */ - {"disconnect", 1, setdisconnector}, /* program to disconnect serial dev. */ - {"welcome", 1, setwelcomer},/* Script to welcome client */ - {"connect-max-attempts", 1, setmaxcon}, /* maximum # connect attempts */ - {"maxconnect", 1, setmaxconnect}, /* specify a maximum connect time */ - {"crtscts", 0, setcrtscts}, /* set h/w flow control */ - {"nocrtscts", 0, setnocrtscts}, /* clear h/w flow control */ - {"-crtscts", 0, setnocrtscts}, /* clear h/w flow control */ - {"xonxoff", 0, setxonxoff}, /* set s/w flow control */ - {"debug", 0, setdebug}, /* Increase debugging level */ - {"kdebug", 1, setkdebug}, /* Enable kernel-level debugging */ - {"domain", 1, setdomain}, /* Add given domain name to hostname*/ - {"mru", 1, setmru}, /* Set MRU value for negotiation */ - {"mtu", 1, setmtu}, /* Set our MTU */ -#ifdef CBCP_SUPPORT - {"callback", 1, setcbcp}, /* Ask for callback */ -#endif - {"netmask", 1, setnetmask}, /* set netmask */ - {"passive", 0, setpassive}, /* Set passive mode */ - {"silent", 0, setsilent}, /* Set silent mode */ - {"modem", 0, setmodem}, /* Use modem control lines */ - {"local", 0, setlocal}, /* Don't use modem control lines */ - {"lock", 0, setlock}, /* Lock serial device (with lock file) */ - {"name", 1, setname}, /* Set local name for authentication */ - {"user", 1, setuser}, /* Set name for auth with peer */ - {"usehostname", 0, setusehostname}, /* Must use hostname for auth. */ - {"remotename", 1, setremote}, /* Set remote name for authentication */ - {"auth", 0, setauth}, /* Require authentication from peer */ - {"noauth", 0, setnoauth}, /* Don't require peer to authenticate */ - {"file", 1, readfile}, /* Take options from a file */ - {"call", 1, callfile}, /* Take options from a privileged file */ - {"defaultroute", 0, setdefaultroute}, /* Add default route */ - {"nodefaultroute", 0, setnodefaultroute}, /* disable defaultroute option */ - {"-defaultroute", 0, setnodefaultroute}, /* disable defaultroute option */ - {"proxyarp", 0, setproxyarp}, /* Add proxy ARP entry */ - {"noproxyarp", 0, setnoproxyarp}, /* disable proxyarp option */ - {"-proxyarp", 0, setnoproxyarp}, /* disable proxyarp option */ - {"persist", 0, setpersist}, /* Keep on reopening connection after close */ - {"nopersist", 0, setnopersist}, /* Turn off persist option */ - {"demand", 0, setdemand}, /* Dial on demand */ - {"login", 0, setdologin}, /* Use system password database for UPAP */ - {"noipdefault", 0, setnoipdflt}, /* Don't use name for default IP adrs */ - {"lcp-echo-failure", 1, setlcpechofails}, /* consecutive echo failures */ - {"lcp-echo-interval", 1, setlcpechointv}, /* time for lcp echo events */ - {"lcp-restart", 1, setlcptimeout}, /* Set timeout for LCP */ - {"lcp-max-terminate", 1, setlcpterm}, /* Set max #xmits for term-reqs */ - {"lcp-max-configure", 1, setlcpconf}, /* Set max #xmits for conf-reqs */ - {"lcp-max-failure", 1, setlcpfails}, /* Set max #conf-naks for LCP */ - {"ipcp-restart", 1, setipcptimeout}, /* Set timeout for IPCP */ - {"ipcp-max-terminate", 1, setipcpterm}, /* Set max #xmits for term-reqs */ - {"ipcp-max-configure", 1, setipcpconf}, /* Set max #xmits for conf-reqs */ - {"ipcp-max-failure", 1, setipcpfails}, /* Set max #conf-naks for IPCP */ - {"pap-restart", 1, setpaptimeout}, /* Set retransmit timeout for PAP */ - {"pap-max-authreq", 1, setpapreqs}, /* Set max #xmits for auth-reqs */ - {"pap-timeout", 1, setpapreqtime}, /* Set time limit for peer PAP auth. */ - {"chap-restart", 1, setchaptimeout}, /* Set timeout for CHAP */ - {"chap-max-challenge", 1, setchapchal}, /* Set max #xmits for challenge */ - {"chap-interval", 1, setchapintv}, /* Set interval for rechallenge */ - {"ipcp-accept-local", 0, setipcpaccl}, /* Accept peer's address for us */ - {"ipcp-accept-remote", 0, setipcpaccr}, /* Accept peer's address for it */ - {"noccp", 0, noccp}, /* Disable CCP negotiation */ - {"-ccp", 0, noccp}, /* Disable CCP negotiation */ - {"bsdcomp", 1, setbsdcomp}, /* request BSD-Compress */ - {"nobsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */ - {"-bsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */ - {"deflate", 1, setdeflate}, /* request Deflate compression */ - {"nodeflate", 0, setnodeflate}, /* don't allow Deflate compression */ - {"-deflate", 0, setnodeflate}, /* don't allow Deflate compression */ - {"nodeflatedraft", 0, setnodeflatedraft}, /* don't use draft deflate # */ - {"predictor1", 0, setpred1comp}, /* request Predictor-1 */ - {"nopredictor1", 0, setnopred1comp},/* don't allow Predictor-1 */ - {"-predictor1", 0, setnopred1comp}, /* don't allow Predictor-1 */ - {"ipparam", 1, setipparam}, /* set ip script parameter */ - {"papcrypt", 0, setpapcrypt}, /* PAP passwords encrypted */ - {"idle", 1, setidle}, /* idle time limit (seconds) */ - {"holdoff", 1, setholdoff}, /* set holdoff time (seconds) */ -/* backwards compat hack */ - {"dns1", 1, setdnsaddr}, /* DNS address for the peer's use */ - {"dns2", 1, setdnsaddr}, /* DNS address for the peer's use */ -/* end compat hack */ - {"ms-dns", 1, setdnsaddr}, /* DNS address for the peer's use */ - {"ms-wins", 1, setwinsaddr}, /* Nameserver for SMB over TCP/IP for peer */ - {"noipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */ - {"-ipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */ - {"--version", 0, showversion}, /* Show version number */ - {"--help", 0, showhelp}, /* Show brief listing of options */ - {"-h", 0, showhelp}, /* ditto */ - -#ifdef PPP_FILTER - {"pdebug", 1, setpdebug}, /* libpcap debugging */ - {"pass-filter", 1, setpassfilter}, /* set filter for packets to pass */ - {"active-filter", 1, setactivefilter}, /* set filter for active pkts */ -#endif - -#ifdef IPX_CHANGE - {"ipx-network", 1, setipxnetwork}, /* IPX network number */ - {"ipxcp-accept-network", 0, setipxanet}, /* Accept peer netowrk */ - {"ipx-node", 1, setipxnode}, /* IPX node number */ - {"ipxcp-accept-local", 0, setipxalcl}, /* Accept our address */ - {"ipxcp-accept-remote", 0, setipxarmt}, /* Accept peer's address */ - {"ipx-routing", 1, setipxrouter}, /* IPX routing proto number */ - {"ipx-router-name", 1, setipxname}, /* IPX router name */ - {"ipxcp-restart", 1, setipxcptimeout}, /* Set timeout for IPXCP */ - {"ipxcp-max-terminate", 1, setipxcpterm}, /* max #xmits for term-reqs */ - {"ipxcp-max-configure", 1, setipxcpconf}, /* max #xmits for conf-reqs */ - {"ipxcp-max-failure", 1, setipxcpfails}, /* max #conf-naks for IPXCP */ -#if 0 - {"ipx-compression", 1, setipxcompression}, /* IPX compression number */ -#endif - {"ipx", 0, setipxproto}, /* Enable IPXCP (and IPX) */ - {"+ipx", 0, setipxproto}, /* Enable IPXCP (and IPX) */ -#endif /* IPX_CHANGE */ - -#ifdef MSLANMAN - {"ms-lanman", 0, setmslanman}, /* Use LanMan psswd when using MS-CHAP */ -#endif - - {NULL, 0, NULL} -}; - - -#ifndef IMPLEMENTATION -#define IMPLEMENTATION "" -#endif - -static const char usage_string[] = "\ -pppd version %s patch level %d%s\n\ -Usage: %s [ options ], where options are:\n\ - Communicate over the named device\n\ - Set the baud rate to \n\ - : Set the local and/or remote interface IP\n\ - addresses. Either one may be omitted.\n\ - asyncmap Set the desired async map to hex \n\ - auth Require authentication from peer\n\ - connect

Invoke shell command

to set up the serial line\n\ - crtscts Use hardware RTS/CTS flow control\n\ - defaultroute Add default route through interface\n\ - file Take options from file \n\ - modem Use modem control lines\n\ - mru Set MRU value to for negotiation\n\ -See pppd(8) for more options.\n\ -"; - -static char *current_option; /* the name of the option being parsed */ -static int privileged_option; /* set iff the current option came from root */ -static char *option_source; /* string saying where the option came from */ - -/* - * parse_args - parse a string of arguments from the command line. - */ -int -parse_args(int argc, char **argv) -{ - char *arg; - struct cmd *cmdp; - int ret; - - privileged_option = privileged; - option_source = "command line"; - while (argc > 0) { - arg = *argv++; - --argc; - - /* - * First see if it's a command. - */ - for (cmdp = cmds; cmdp->cmd_name; cmdp++) - if (!strcmp(arg, cmdp->cmd_name)) - break; - - if (cmdp->cmd_name != NULL) { - if (argc < cmdp->num_args) { - option_error("too few parameters for option %s", arg); - return 0; - } - current_option = arg; - if (!(*cmdp->cmd_func)(argv)) - return 0; - argc -= cmdp->num_args; - argv += cmdp->num_args; - - } else { - /* - * Maybe a tty name, speed or IP address? - */ - if ((ret = setdevname(arg, 0)) == 0 - && (ret = setspeed(arg)) == 0 - && (ret = setipaddr(arg)) == 0) { - option_error("unrecognized option '%s'", arg); - usage(); - return 0; - } - if (ret < 0) /* error */ - return 0; - } - } - return 1; -} - -/* - * scan_args - scan the command line arguments to get the tty name, - * if specified. - */ -void -scan_args(int argc, char **argv) -{ - char *arg; - struct cmd *cmdp; - - while (argc > 0) { - arg = *argv++; - --argc; - - /* Skip options and their arguments */ - for (cmdp = cmds; cmdp->cmd_name; cmdp++) - if (!strcmp(arg, cmdp->cmd_name)) - break; - - if (cmdp->cmd_name != NULL) { - argc -= cmdp->num_args; - argv += cmdp->num_args; - continue; - } - - /* Check if it's a tty name and copy it if so */ - setdevname(arg, 1); - } -} - -/* - * usage - print out a message telling how to use the program. - */ -void -usage(void) -{ - if (phase == PHASE_INITIALIZE) - fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION, - progname); -} - -/* - * showhelp - print out usage message and exit. - */ -static int -showhelp(char **argv) -{ - if (phase == PHASE_INITIALIZE) { - usage(); - exit(0); - } - return 0; -} - -/* - * showversion - print out the version number and exit. - */ -static int -showversion(char **argv) -{ - if (phase == PHASE_INITIALIZE) { - fprintf(stderr, "pppd version %s patch level %d%s\n", - VERSION, PATCHLEVEL, IMPLEMENTATION); - exit(0); - } - return 0; -} - -/* - * options_from_file - Read a string of options from a file, - * and interpret them. - */ -int -options_from_file(char *filename, int must_exist, int check_prot, int priv) -{ - FILE *f; - int i, newline, ret; - struct cmd *cmdp; - int oldpriv; - char *argv[MAXARGS]; - char args[MAXARGS][MAXWORDLEN]; - char cmd[MAXWORDLEN]; - - if ((f = fopen(filename, "r")) == NULL) { - if (!must_exist && errno == ENOENT) - return 1; - option_error("Can't open options file %s: %m", filename); - return 0; - } - if (check_prot && !readable(fileno(f))) { - option_error("Can't open options file %s: access denied", filename); - fclose(f); - return 0; - } - - oldpriv = privileged_option; - privileged_option = priv; - ret = 0; - while (getword(f, cmd, &newline, filename)) { - /* - * First see if it's a command. - */ - for (cmdp = cmds; cmdp->cmd_name; cmdp++) - if (!strcmp(cmd, cmdp->cmd_name)) - break; - - if (cmdp->cmd_name != NULL) { - for (i = 0; i < cmdp->num_args; ++i) { - if (!getword(f, args[i], &newline, filename)) { - option_error( - "In file %s: too few parameters for option '%s'", - filename, cmd); - goto err; - } - argv[i] = args[i]; - } - current_option = cmd; - if (!(*cmdp->cmd_func)(argv)) - goto err; - - } else { - /* - * Maybe a tty name, speed or IP address? - */ - if ((i = setdevname(cmd, 0)) == 0 - && (i = setspeed(cmd)) == 0 - && (i = setipaddr(cmd)) == 0) { - option_error("In file %s: unrecognized option '%s'", - filename, cmd); - goto err; - } - if (i < 0) /* error */ - goto err; - } - } - ret = 1; - -err: - fclose(f); - privileged_option = oldpriv; - 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; - - pw = getpwuid(getuid()); - if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) - return 1; - file = _PATH_USEROPT; - path = malloc(strlen(user) + strlen(file) + 2); - if (path == NULL) - novm("init file name"); - strcpy(path, user); - strcat(path, "/"); - strcat(path, file); - ret = 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. - */ -int -options_for_tty(void) -{ - char *dev, *path, *p; - int ret; - - dev = devnam; - if (strncmp(dev, _PATH_DEV, sizeof _PATH_DEV - 1) == 0) - dev += 5; - if (strcmp(dev, "tty") == 0) - return 1; /* don't look for /etc/ppp/options.tty */ - path = malloc(strlen(_PATH_TTYOPT) + strlen(dev) + 1); - if (path == NULL) - novm("tty init file name"); - strcpy(path, _PATH_TTYOPT); - /* Turn slashes into dots, for Solaris case (e.g. /dev/term/a) */ - for (p = path + strlen(path); *dev != 0; ++dev) - *p++ = (*dev == '/'? '.': *dev); - *p = 0; - ret = options_from_file(path, 0, 0, 1); - free(path); - return ret; -} - -/* - * option_error - print a message about an error in an option. - * The message is logged, and also sent to - * stderr if phase == PHASE_INITIALIZE. - */ -void -option_error __V((char *fmt, ...)) -{ - va_list args; - char buf[256]; - -#if __STDC__ - va_start(args, fmt); -#else - char *fmt; - va_start(args); - fmt = va_arg(args, char *); -#endif - vfmtmsg(buf, sizeof(buf), fmt, args); - va_end(args); - if (phase == PHASE_INITIALIZE) - fprintf(stderr, "%s: %s\n", progname, buf); - syslog(LOG_ERR, "%s", buf); -} - -/* - * readable - check if a file is readable by the real user. - */ -static int -readable(int fd) -{ - uid_t uid; - int ngroups, i; - struct stat sbuf; - GIDSET_TYPE groups[NGROUPS_MAX]; - - 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; - ngroups = getgroups(NGROUPS_MAX, groups); - for (i = 0; i < ngroups; ++i) - if (sbuf.st_gid == groups[i]) - return sbuf.st_mode & S_IRGRP; - return sbuf.st_mode & S_IROTH; -} - -/* - * 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; - - /* - * 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; - } - - /* - * Save the delimiter for quoted strings. - */ - if (!escape && (c == '"' || c == '\'')) { - quoted = c; - c = getc(f); - } else - quoted = 0; - - /* - * 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-1) - word[len] = value; - ++len; - - if (!got) - c = getc(f); - continue; - - } - - /* - * Not escaped: see if we've reached the end of the word. - */ - if (quoted) { - if (c == quoted) - break; - } else { - if (isspace(c) || c == '#') { - ungetc (c, f); - break; - } - } - - /* - * Backslash starts an escape sequence. - */ - if (c == '\\') { - escape = 1; - c = getc(f); - continue; - } - - /* - * An ordinary character: store it in the word and get another. - */ - if (len < MAXWORDLEN-1) - word[len] = c; - ++len; - - c = getc(f); - } - - /* - * End of the word: check for errors. - */ - if (c == EOF) { - if (ferror(f)) { - if (errno == 0) - errno = EIO; - 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; - } - - /* - * Warn if the word was too long, and append a terminating null. - */ - if (len >= MAXWORDLEN) { - 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) { - 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. - */ -static int -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 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) { - option_error("call option value may not contain .. or start with /"); - return 0; - } - - l = strlen(arg) + strlen(_PATH_PEERFILES) + 1; - if ((fname = (char *) malloc(l)) == NULL) - novm("call file name"); - strcpy(fname, _PATH_PEERFILES); - strcat(fname, arg); - - ok = options_from_file(fname, 1, 1, 1); - - free(fname); - return ok; -} - - -/* - * setdebug - Set debug (command line argument). - */ -static int -setdebug(char **argv) -{ - debug++; - return (1); -} - -/* - * setkdebug - Set kernel debugging level. - */ -static int -setkdebug(char **argv) -{ - return int_option(*argv, &kdebugflag); -} - -#ifdef PPP_FILTER -/* - * setpdebug - Set libpcap debugging level. - */ -static int -setpdebug(char **argv) -{ - return int_option(*argv, &dflag); -} - -/* - * setpassfilter - Set the pass filter for packets - */ -static int -setpassfilter(char **argv) -{ - pc.linktype = DLT_PPP; - pc.snapshot = PPP_HDRLEN; - - if (pcap_compile(&pc, &pass_filter, *argv, 1, netmask) == 0) - return 1; - option_error("error in pass-filter expression: %s\n", pcap_geterr(&pc)); - return 0; -} - -/* - * setactivefilter - Set the active filter for packets - */ -static int -setactivefilter(char **argv) -{ - pc.linktype = DLT_PPP; - pc.snapshot = PPP_HDRLEN; - - if (pcap_compile(&pc, &active_filter, *argv, 1, netmask) == 0) - return 1; - option_error("error in active-filter expression: %s\n", pcap_geterr(&pc)); - return 0; -} -#endif - -/* - * noopt - Disable all options. - */ -static int -noopt(char **argv) -{ - BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options)); - BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options)); - BZERO((char *) &ipcp_wantoptions[0], sizeof (struct ipcp_options)); - BZERO((char *) &ipcp_allowoptions[0], sizeof (struct ipcp_options)); - -#ifdef IPX_CHANGE - BZERO((char *) &ipxcp_wantoptions[0], sizeof (struct ipxcp_options)); - BZERO((char *) &ipxcp_allowoptions[0], sizeof (struct ipxcp_options)); -#endif /* IPX_CHANGE */ - - return (1); -} - -/* - * noaccomp - Disable Address/Control field compression negotiation. - */ -static int -noaccomp(char **argv) -{ - lcp_wantoptions[0].neg_accompression = 0; - lcp_allowoptions[0].neg_accompression = 0; - return (1); -} - - -/* - * noasyncmap - Disable async map negotiation. - */ -static int -noasyncmap(char **argv) -{ - lcp_wantoptions[0].neg_asyncmap = 0; - lcp_allowoptions[0].neg_asyncmap = 0; - return (1); -} - - -/* - * noip - Disable IP and IPCP. - */ -static int -noip(char **argv) -{ - ipcp_protent.enabled_flag = 0; - return (1); -} - - -/* - * nomagicnumber - Disable magic number negotiation. - */ -static int -nomagicnumber(char **argv) -{ - lcp_wantoptions[0].neg_magicnumber = 0; - lcp_allowoptions[0].neg_magicnumber = 0; - return (1); -} - - -/* - * nomru - Disable mru negotiation. - */ -static int -nomru(char **argv) -{ - lcp_wantoptions[0].neg_mru = 0; - lcp_allowoptions[0].neg_mru = 0; - return (1); -} - - -/* - * setmru - Set MRU for negotiation. - */ -static int -setmru(char **argv) -{ - u_int32_t mru; - - if (!number_option(*argv, &mru, 0)) - return 0; - lcp_wantoptions[0].mru = mru; - lcp_wantoptions[0].neg_mru = 1; - return (1); -} - - -/* - * setmru - Set the largest MTU we'll use. - */ -static int -setmtu(char **argv) -{ - u_int32_t mtu; - - if (!number_option(*argv, &mtu, 0)) - return 0; - if (mtu < MINMRU || mtu > MAXMRU) { - option_error("mtu option value of %u is too %s", mtu, - (mtu < MINMRU? "small": "large")); - return 0; - } - lcp_allowoptions[0].mru = mtu; - return (1); -} - -#ifdef CBCP_SUPPORT -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); -} -#endif - -/* - * nopcomp - Disable Protocol field compression negotiation. - */ -static int -nopcomp(char **argv) -{ - lcp_wantoptions[0].neg_pcompression = 0; - lcp_allowoptions[0].neg_pcompression = 0; - return (1); -} - - -/* - * setpassive - Set passive mode (don't give up if we time out sending - * LCP configure-requests). - */ -static int -setpassive(char **argv) -{ - lcp_wantoptions[0].passive = 1; - return (1); -} - - -/* - * setsilent - Set silent mode (don't start sending LCP configure-requests - * until we get one from the peer). - */ -static int -setsilent(char **argv) -{ - lcp_wantoptions[0].silent = 1; - return 1; -} - - -/* - * nopap - Disable PAP authentication with peer. - */ -static int -nopap(char **argv) -{ - refuse_pap = 1; - return (1); -} - - -/* - * reqpap - Require PAP authentication from peer. - */ -static int -reqpap(char **argv) -{ - lcp_wantoptions[0].neg_upap = 1; - setauth(NULL); - return 1; -} - -#if OLD_OPTIONS -/* - * setupapfile - specifies UPAP info for authenticating with peer. - */ -static int -setupapfile(char **argv) -{ - FILE * ufile; - int l; - - lcp_allowoptions[0].neg_upap = 1; - - /* open user info file */ - if ((ufile = fopen(*argv, "r")) == NULL) { - option_error("unable to open user login data file %s", *argv); - return 0; - } - if (!readable(fileno(ufile))) { - option_error("%s: access denied", *argv); - return 0; - } - check_access(ufile, *argv); - - /* get username */ - if (fgets(user, MAXNAMELEN - 1, ufile) == NULL - || fgets(passwd, MAXSECRETLEN - 1, ufile) == NULL){ - option_error("unable to read user login data file %s", *argv); - return 0; - } - fclose(ufile); - - /* get rid of newlines */ - l = strlen(user); - if (l > 0 && user[l-1] == '\n') - user[l-1] = 0; - l = strlen(passwd); - if (l > 0 && passwd[l-1] == '\n') - passwd[l-1] = 0; - - return (1); -} -#endif - -/* - * nochap - Disable CHAP authentication with peer. - */ -static int -nochap(char **argv) -{ - refuse_chap = 1; - return (1); -} - - -/* - * reqchap - Require CHAP authentication from peer. - */ -static int -reqchap(char **argv) -{ - lcp_wantoptions[0].neg_chap = 1; - setauth(NULL); - return (1); -} - - -/* - * setnovj - disable vj compression - */ -static int -setnovj(char **argv) -{ - ipcp_wantoptions[0].neg_vj = 0; - ipcp_allowoptions[0].neg_vj = 0; - return (1); -} - - -/* - * setnovjccomp - disable VJ connection-ID compression - */ -static int -setnovjccomp(char **argv) -{ - ipcp_wantoptions[0].cflag = 0; - ipcp_allowoptions[0].cflag = 0; - return 1; -} - - -/* - * setvjslots - set maximum number of connection slots for VJ compression - */ -static int -setvjslots(char **argv) -{ - int value; - - if (!int_option(*argv, &value)) - return 0; - if (value < 2 || value > 16) { - option_error("vj-max-slots value must be between 2 and 16"); - return 0; - } - ipcp_wantoptions [0].maxslotindex = - ipcp_allowoptions[0].maxslotindex = value - 1; - return 1; -} - - -/* - * setconnector - Set a program to connect to a serial line - */ -static int -setconnector(char **argv) -{ - connector = strdup(*argv); - if (connector == NULL) - novm("connect script"); - connector_info.priv = privileged_option; - connector_info.source = option_source; - - return (1); -} - -/* - * setdisconnector - Set a program to disconnect from the serial line - */ -static int -setdisconnector(char **argv) -{ - disconnector = strdup(*argv); - if (disconnector == NULL) - novm("disconnect script"); - disconnector_info.priv = privileged_option; - disconnector_info.source = option_source; - - return (1); -} - -/* - * setwelcomer - Set a program to welcome a client after connection - */ -static int -setwelcomer(char **argv) -{ - welcomer = strdup(*argv); - if (welcomer == NULL) - novm("welcome script"); - welcomer_info.priv = privileged_option; - welcomer_info.source = option_source; - - return (1); -} - -static int -setmaxcon(char **argv) -{ - return int_option(*argv, &max_con_attempts); -} - -/* - * setmaxconnect - Set the maximum connect time - */ -static int -setmaxconnect(char **argv) -{ - int value; - - if (!int_option(*argv, &value)) - return 0; - if (value < 0) { - option_error("maxconnect time must be positive"); - return 0; - } - if (maxconnect > 0 && (value == 0 || value > maxconnect)) { - option_error("maxconnect time cannot be increased"); - return 0; - } - maxconnect = value; - return 1; -} - -/* - * setdomain - Set domain name to append to hostname - */ -static int -setdomain(char **argv) -{ - if (!privileged_option) { - option_error("using the domain option requires root privilege"); - return 0; - } - gethostname(hostname, MAXNAMELEN); - if (**argv != 0) { - if (**argv != '.') - strncat(hostname, ".", MAXNAMELEN - strlen(hostname)); - strncat(hostname, *argv, MAXNAMELEN - strlen(hostname)); - } - hostname[MAXNAMELEN-1] = 0; - return (1); -} - - -/* - * setasyncmap - add bits to asyncmap (what we request peer to escape). - */ -static int -setasyncmap(char **argv) -{ - u_int32_t asyncmap; - - if (!number_option(*argv, &asyncmap, 16)) - return 0; - lcp_wantoptions[0].asyncmap |= asyncmap; - lcp_wantoptions[0].neg_asyncmap = 1; - 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) { - option_error("escape parameter contains invalid hex number '%s'", - p); - return 0; - } - p = endp; - if (n < 0 || (0x20 <= n && n <= 0x3F) || n == 0x5E || n > 0xFF) { - option_error("can't escape character 0x%x", n); - ret = 0; - } else - xmit_accm[0][n >> 5] |= 1 << (n & 0x1F); - while (*p == ',' || *p == ' ') - ++p; - } - return ret; -} - - -/* - * setspeed - Set the speed. - */ -static int -setspeed(char *arg) -{ - char *ptr; - int spd; - - spd = strtol(arg, &ptr, 0); - if (ptr == arg || *ptr != 0 || spd == 0) - return 0; - inspeed = spd; - return 1; -} - - -/* - * setdevname - Set the device name. - */ -static int -setdevname(char *cp, int quiet) -{ - struct stat statbuf; - char dev[MAXPATHLEN]; - - if (*cp == 0) - return 0; - - if (strncmp(_PATH_DEV, cp, sizeof _PATH_DEV - 1) != 0) { - strcpy(dev, _PATH_DEV); - strncat(dev, cp, MAXPATHLEN - sizeof _PATH_DEV - 1); - dev[MAXPATHLEN-1] = 0; - cp = dev; - } - - /* - * Check if there is a device by this name. - */ - if (stat(cp, &statbuf) < 0) { - if (errno == ENOENT || quiet) - return 0; - option_error("Couldn't stat %s: %m", cp); - return -1; - } - - strncpy(devnam, cp, MAXPATHLEN); - devnam[MAXPATHLEN-1] = 0; - default_device = FALSE; - devnam_info.priv = privileged_option; - devnam_info.source = option_source; - - return 1; -} - - -/* - * setipaddr - Set the IP address - */ -int -setipaddr(char *arg) -{ - struct hostent *hp; - char *colon; - u_int32_t local, remote; - ipcp_options *wo = &ipcp_wantoptions[0]; - - /* - * IP address pair separated by ":". - */ - if ((colon = strchr(arg, ':')) == NULL) - return 0; - - /* - * If colon first character, then no local addr. - */ - if (colon != arg) { - *colon = '\0'; - if ((local = inet_addr(arg)) == -1) { - if ((hp = gethostbyname(arg)) == NULL) { - option_error("unknown host: %s", arg); - return -1; - } else { - local = *(u_int32_t *)hp->h_addr; - } - } - if (bad_ip_adrs(local)) { - option_error("bad local IP address %s", ip_ntoa(local)); - return -1; - } - if (local != 0) - wo->ouraddr = local; - *colon = ':'; - } - - /* - * If colon last character, then no remote addr. - */ - if (*++colon != '\0') { - if ((remote = inet_addr(colon)) == -1) { - if ((hp = gethostbyname(colon)) == NULL) { - option_error("unknown host: %s", colon); - return -1; - } else { - remote = *(u_int32_t *)hp->h_addr; - if (remote_name[0] == 0) { - strncpy(remote_name, colon, MAXNAMELEN); - remote_name[MAXNAMELEN-1] = 0; - } - } - } - if (bad_ip_adrs(remote)) { - option_error("bad remote IP address %s", ip_ntoa(remote)); - return -1; - } - if (remote != 0) - wo->hisaddr = remote; - } - - return 1; -} - - -/* - * setnoipdflt - disable setipdefault() - */ -static int -setnoipdflt(char **argv) -{ - disable_defaultip = 1; - return 1; -} - - -/* - * setipcpaccl - accept peer's idea of our address - */ -static int -setipcpaccl(char **argv) -{ - ipcp_wantoptions[0].accept_local = 1; - return 1; -} - - -/* - * setipcpaccr - accept peer's idea of its address - */ -static int -setipcpaccr(char **argv) -{ - ipcp_wantoptions[0].accept_remote = 1; - return 1; -} - - -/* - * setnetmask - set the netmask to be used on the interface. - */ -static int -setnetmask(char **argv) -{ - struct in_addr mask; - - if (!inet_aton(*argv, &mask) || (netmask & ~mask.s_addr)) { - fprintf(stderr, "Invalid netmask %s\n", *argv); - return (0); - } - - netmask = mask.s_addr; - return (1); -} - -static int -setcrtscts(char **argv) -{ - crtscts = 1; - return (1); -} - -static int -setnocrtscts(char **argv) -{ - crtscts = -1; - 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); -} - -static int -setnodetach(char **argv) -{ - nodetach = 1; - return (1); -} - -static int -setupdetach(char **argv) -{ - nodetach = -1; - return (1); -} - -static int -setdemand(char **argv) -{ - demand = 1; - persist = 1; - return 1; -} - -static int -setmodem(char **argv) -{ - modem = 1; - return 1; -} - -static int -setlocal(char **argv) -{ - modem = 0; - return 1; -} - -static int -setlock(char **argv) -{ - lockflag = 1; - return 1; -} - -static int -setusehostname(char **argv) -{ - usehostname = 1; - return 1; -} - -static int -setname(char **argv) -{ - if (!privileged_option) { - option_error("using the name option requires root privilege"); - return 0; - } - strncpy(our_name, argv[0], MAXNAMELEN); - our_name[MAXNAMELEN-1] = 0; - return 1; -} - -static int -setuser(char **argv) -{ - strncpy(user, argv[0], MAXNAMELEN); - user[MAXNAMELEN-1] = 0; - return 1; -} - -static int -setremote(char **argv) -{ - strncpy(remote_name, argv[0], MAXNAMELEN); - remote_name[MAXNAMELEN-1] = 0; - return 1; -} - -static int -setauth(char **argv) -{ - auth_required = 1; - if (privileged_option > auth_req_info.priv) { - auth_req_info.priv = privileged_option; - auth_req_info.source = option_source; - } - return 1; -} - -static int -setnoauth(char **argv) -{ - if (auth_required && privileged_option < auth_req_info.priv) { - option_error("cannot override auth option set by %s", - auth_req_info.source); - return 0; - } - auth_required = 0; - return 1; -} - -static int -setdefaultroute(char **argv) -{ - if (!ipcp_allowoptions[0].default_route) { - option_error("defaultroute option is disabled"); - return 0; - } - ipcp_wantoptions[0].default_route = 1; - return 1; -} - -static int -setnodefaultroute(char **argv) -{ - ipcp_allowoptions[0].default_route = 0; - ipcp_wantoptions[0].default_route = 0; - return 1; -} - -static int -setproxyarp(char **argv) -{ - if (!ipcp_allowoptions[0].proxy_arp) { - option_error("proxyarp option is disabled"); - return 0; - } - ipcp_wantoptions[0].proxy_arp = 1; - return 1; -} - -static int -setnoproxyarp(char **argv) -{ - ipcp_wantoptions[0].proxy_arp = 0; - ipcp_allowoptions[0].proxy_arp = 0; - return 1; -} - -static int -setpersist(char **argv) -{ - persist = 1; - return 1; -} - -static int -setnopersist(char **argv) -{ - persist = 0; - return 1; -} - -static int -setdologin(char **argv) -{ - uselogin = 1; - return 1; -} - -/* - * Functions to set the echo interval for modem-less monitors - */ - -static int -setlcpechointv(char **argv) -{ - return int_option(*argv, &lcp_echo_interval); -} - -static int -setlcpechofails(char **argv) -{ - return int_option(*argv, &lcp_echo_fails); -} - -/* - * Functions to set timeouts, max transmits, etc. - */ -static int -setlcptimeout(char **argv) -{ - return int_option(*argv, &lcp_fsm[0].timeouttime); -} - -static int -setlcpterm(char **argv) -{ - return int_option(*argv, &lcp_fsm[0].maxtermtransmits); -} - -static int -setlcpconf(char **argv) -{ - return int_option(*argv, &lcp_fsm[0].maxconfreqtransmits); -} - -static int -setlcpfails(char **argv) -{ - return int_option(*argv, &lcp_fsm[0].maxnakloops); -} - -static int -setipcptimeout(char **argv) -{ - return int_option(*argv, &ipcp_fsm[0].timeouttime); -} - -static int -setipcpterm(char **argv) -{ - return int_option(*argv, &ipcp_fsm[0].maxtermtransmits); -} - -static int -setipcpconf(char **argv) -{ - return int_option(*argv, &ipcp_fsm[0].maxconfreqtransmits); -} - -static int -setipcpfails(char **argv) -{ - return int_option(*argv, &lcp_fsm[0].maxnakloops); -} - -static int -setpaptimeout(char **argv) -{ - return int_option(*argv, &upap[0].us_timeouttime); -} - -static int -setpapreqtime(char **argv) -{ - return int_option(*argv, &upap[0].us_reqtimeout); -} - -static int -setpapreqs(char **argv) -{ - return int_option(*argv, &upap[0].us_maxtransmits); -} - -static int -setchaptimeout(char **argv) -{ - return int_option(*argv, &chap[0].timeouttime); -} - -static int -setchapchal(char **argv) -{ - return int_option(*argv, &chap[0].max_transmits); -} - -static int -setchapintv(char **argv) -{ - return int_option(*argv, &chap[0].chal_interval); -} - -static int -noccp(char **argv) -{ - ccp_protent.enabled_flag = 0; - return 1; -} - -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) { - 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))) { - 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; - return 1; -} - -static int -setnobsdcomp(char **argv) -{ - ccp_wantoptions[0].bsd_compress = 0; - ccp_allowoptions[0].bsd_compress = 0; - 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) { - 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))) { - option_error("deflate option values must be 0 or %d .. %d", - DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE); - return 0; - } - 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; - - /* XXX copy over settings for switch compatibility */ - ccp_wantoptions[0].baddeflate = ccp_wantoptions[0].deflate; - ccp_wantoptions[0].baddeflate_size = ccp_wantoptions[0].deflate_size; - ccp_allowoptions[0].baddeflate = ccp_allowoptions[0].deflate; - ccp_allowoptions[0].baddeflate_size = ccp_allowoptions[0].deflate_size; - - return 1; -} - -static int -setnodeflate(char **argv) -{ - ccp_wantoptions[0].deflate = 0; - ccp_allowoptions[0].deflate = 0; - return 1; -} - -static int -setnodeflatedraft(char **argv) -{ - ccp_wantoptions[0].deflate_draft = 0; - ccp_allowoptions[0].deflate_draft = 0; - return 1; -} - -static int -setpred1comp(char **argv) -{ - ccp_wantoptions[0].predictor_1 = 1; - ccp_allowoptions[0].predictor_1 = 1; - return 1; -} - -static int -setnopred1comp(char **argv) -{ - ccp_wantoptions[0].predictor_1 = 0; - ccp_allowoptions[0].predictor_1 = 0; - return 1; -} - -static int -setipparam(char **argv) -{ - ipparam = strdup(*argv); - if (ipparam == NULL) - novm("ipparam string"); - - return 1; -} - -static int -setpapcrypt(char **argv) -{ - cryptpap = 1; - return 1; -} - -static int -setidle(char **argv) -{ - return int_option(*argv, &idle_time_limit); -} - -static int -setholdoff(char **argv) -{ - return int_option(*argv, &holdoff); -} - -/* - * setdnsaddr - set the dns address(es) - */ -static int -setdnsaddr(char **argv) -{ - u_int32_t dns; - struct hostent *hp; - - dns = inet_addr(*argv); - if (dns == -1) { - if ((hp = gethostbyname(*argv)) == NULL) { - option_error("invalid address parameter '%s' for ms-dns option", - *argv); - return 0; - } - dns = *(u_int32_t *)hp->h_addr; - } - - /* if there is no primary then update it. */ - if (ipcp_allowoptions[0].dnsaddr[0] == 0) - ipcp_allowoptions[0].dnsaddr[0] = dns; - - /* always set the secondary address value to the same 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 == -1) { - if ((hp = gethostbyname(*argv)) == NULL) { - option_error("invalid address parameter '%s' for ms-wins option", - *argv); - return 0; - } - wins = *(u_int32_t *)hp->h_addr; - } - - /* if there is no primary then update it. */ - if (ipcp_allowoptions[0].winsaddr[0] == 0) - ipcp_allowoptions[0].winsaddr[0] = wins; - - /* always set the secondary address value to the same value. */ - ipcp_allowoptions[0].winsaddr[1] = wins; - - return (1); -} - -#ifdef IPX_CHANGE -static int -setipxrouter(char **argv) -{ - ipxcp_wantoptions[0].neg_router = 1; - ipxcp_allowoptions[0].neg_router = 1; - return int_option(*argv, &ipxcp_wantoptions[0].router); -} - -static int -setipxname(char **argv) -{ - char *dest = ipxcp_wantoptions[0].name; - char *src = *argv; - int count; - char ch; - - ipxcp_wantoptions[0].neg_name = 1; - ipxcp_allowoptions[0].neg_name = 1; - memset (dest, '\0', sizeof (ipxcp_wantoptions[0].name)); - - count = 0; - while (*src) { - ch = *src++; - if (! isalnum (ch) && ch != '_') { - option_error("IPX router name must be alphanumeric or _"); - return 0; - } - - if (count >= sizeof (ipxcp_wantoptions[0].name)) { - option_error("IPX router name is limited to %d characters", - sizeof (ipxcp_wantoptions[0].name) - 1); - return 0; - } - - dest[count++] = toupper (ch); - } - - return 1; -} - -static int -setipxcptimeout(char **argv) -{ - return int_option(*argv, &ipxcp_fsm[0].timeouttime); -} - -static int -setipxcpterm(char **argv) -{ - return int_option(*argv, &ipxcp_fsm[0].maxtermtransmits); -} - -static int -setipxcpconf(char **argv) -{ - return int_option(*argv, &ipxcp_fsm[0].maxconfreqtransmits); -} - -static int -setipxcpfails(char **argv) -{ - return int_option(*argv, &ipxcp_fsm[0].maxnakloops); -} - -static int -setipxnetwork(char **argv) -{ - u_int32_t v; - - if (!number_option(*argv, &v, 16)) - return 0; - - ipxcp_wantoptions[0].our_network = (int) v; - ipxcp_wantoptions[0].neg_nn = 1; - return 1; -} - -static int -setipxanet(char **argv) -{ - ipxcp_wantoptions[0].accept_network = 1; - ipxcp_allowoptions[0].accept_network = 1; - return 1; -} - -static int -setipxalcl(char **argv) -{ - ipxcp_wantoptions[0].accept_local = 1; - ipxcp_allowoptions[0].accept_local = 1; - return 1; -} - -static int -setipxarmt(char **argv) -{ - ipxcp_wantoptions[0].accept_remote = 1; - ipxcp_allowoptions[0].accept_remote = 1; - return 1; -} - -static u_char * -setipxnodevalue(u_char *src, u_char *dst) -{ - int indx; - int item; - - for (;;) { - if (!isxdigit (*src)) - break; - - for (indx = 0; indx < 5; ++indx) { - dst[indx] <<= 4; - dst[indx] |= (dst[indx + 1] >> 4) & 0x0F; - } - - item = toupper (*src) - '0'; - if (item > 9) - item -= 7; - - dst[5] = (dst[5] << 4) | item; - ++src; - } - return src; -} - -static int -setipxnode(char **argv) -{ - char *end; - - memset (&ipxcp_wantoptions[0].our_node[0], 0, 6); - memset (&ipxcp_wantoptions[0].his_node[0], 0, 6); - - end = setipxnodevalue (*argv, &ipxcp_wantoptions[0].our_node[0]); - if (*end == ':') - end = setipxnodevalue (++end, &ipxcp_wantoptions[0].his_node[0]); - - if (*end == '\0') { - ipxcp_wantoptions[0].neg_node = 1; - return 1; - } - - option_error("invalid parameter '%s' for ipx-node option", *argv); - return 0; -} - -static int -setipxproto(char **argv) -{ - ipxcp_protent.enabled_flag = 1; - return 1; -} - -static int -resetipxproto(char **argv) -{ - ipxcp_protent.enabled_flag = 0; - return 1; -} -#else - -static int -resetipxproto(char **argv) -{ - return 1; -} -#endif /* IPX_CHANGE */ - -#ifdef MSLANMAN -static int -setmslanman(char **argv) -{ - ms_lanman = 1; - return (1); -} -#endif diff --git a/usr.sbin/pppd/patchlevel.h b/usr.sbin/pppd/patchlevel.h deleted file mode 100644 index 43f90cc3cc..0000000000 --- a/usr.sbin/pppd/patchlevel.h +++ /dev/null @@ -1,7 +0,0 @@ -/* $FreeBSD: src/usr.sbin/pppd/patchlevel.h,v 1.10 1999/08/28 01:19:07 peter Exp $ */ -/* $DragonFly: src/usr.sbin/pppd/patchlevel.h,v 1.2 2003/06/17 04:30:01 dillon Exp $ */ -#define PATCHLEVEL 5 - -#define VERSION "2.3" -#define IMPLEMENTATION "" -#define DATE "4 May 1998" diff --git a/usr.sbin/pppd/pathnames.h b/usr.sbin/pppd/pathnames.h deleted file mode 100644 index 96c2ca8160..0000000000 --- a/usr.sbin/pppd/pathnames.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * define path names - * - * $FreeBSD: src/usr.sbin/pppd/pathnames.h,v 1.9.2.1 2002/07/01 03:02:03 mdodd Exp $ - * $DragonFly: src/usr.sbin/pppd/pathnames.h,v 1.2 2003/06/17 04:30:01 dillon Exp $ - */ - -#ifdef HAVE_PATHS_H -#include - -#else -#define _PATH_VARRUN "/etc/ppp/" -#define _PATH_DEVNULL "/dev/null" -#endif - -#define _PATH_UPAPFILE "/etc/ppp/pap-secrets" -#define _PATH_CHAPFILE "/etc/ppp/chap-secrets" -#define _PATH_SYSOPTIONS "/etc/ppp/options" -#define _PATH_IPUP "/etc/ppp/ip-up" -#define _PATH_IPDOWN "/etc/ppp/ip-down" -#define _PATH_AUTHUP "/etc/ppp/auth-up" -#define _PATH_AUTHDOWN "/etc/ppp/auth-down" -#define _PATH_TTYOPT "/etc/ppp/options." -#define _PATH_CONNERRS "/var/log/connect-errors" -#define _PATH_USEROPT ".ppprc" -#define _PATH_PEERFILES "/etc/ppp/peers/" -#define _PATH_PPPDENY "/etc/ppp/ppp.deny" -#define _PATH_PPPSHELLS "/etc/ppp/ppp.shells" - -#ifdef IPX_CHANGE -#define _PATH_IPXUP "/etc/ppp/ipx-up" -#define _PATH_IPXDOWN "/etc/ppp/ipx-down" -#endif /* IPX_CHANGE */ diff --git a/usr.sbin/pppd/pppd.8 b/usr.sbin/pppd/pppd.8 deleted file mode 100644 index d8b7bca465..0000000000 --- a/usr.sbin/pppd/pppd.8 +++ /dev/null @@ -1,1686 +0,0 @@ -.Dd August 31, 2013 -.Dt PPPD 8 -.Os -.Sh NAME -.Nm pppd -.Nd Point-to-Point Protocol daemon -.Sh SYNOPSIS -.Nm -.Op Ar tty_name -.Op Ar speed -.Op Ar options -.Sh DESCRIPTION -The Point-to-Point Protocol (PPP) provides a method for transmitting -datagrams over serial point-to-point links. -PPP is composed of three parts: a method for encapsulating datagrams over -serial links, an extensible Link Control Protocol (LCP), and -a family of Network Control Protocols (NCP) for establishing -and configuring different network-layer protocols. -.Pp -The encapsulation scheme is provided by driver code in the kernel. -.Nm -provides the basic LCP, authentication support, and an NCP for -establishing and configuring the Internet Protocol (IP) (called the IP -Control Protocol, IPCP). -.Ss FREQUENTLY USED OPTIONS -.Bl -ohang -offset indent -.It Ar tty_name -Communicate over the named device. -The string -.Dq /dev/ -is prepended if necessary. -If no device name is given, or if the name of the terminal -connected to the standard input is given, -.Nm -will use that terminal, and will not fork to put itself in the -background. -This option is privileged if the -.Cm noauth -option is used. -.It Ar speed -Set the baud rate to -.Ar speed -(a decimal number). -On systems such as -.Bx 4.4 -and -.Nx , -any speed can be specified, providing that it is -supported by the serial device driver. -Other systems (e.g. SunOS, Linux) allow only a limited set of speeds. -.It Cm active-filter Ar filter-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 -.Cm idle -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 -.Ar filter-expression -syntax is as described for -.Xr tcpdump 1 , -except that qualifiers which are inappropriate for a PPP link, such as -.Cm ether -and -.Cm arp , -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 only available if both the kernel and -.Nm -were compiled with -.Dv PPP_FILTER -defined. -.It Cm asyncmap Ar map -Set the async character map to -.Ar map . -This map describes which control characters cannot be successfully -received over the serial line. -.Nm -will ask the peer to send these characters as a 2-byte -escape sequence. -The argument is a 32 bit hex number with each bit -representing a character to escape. -Bit 0 (00000001) represents the character 0x00; -bit 31 (80000000) represents the character 0x1f or ^_. -If multiple -.Cm asyncmap -options are given, the values are ORed together. -If no -.Cm asyncmap -option is given, no async character -map will be negotiated for the receive direction; -the peer should then escape all control characters. -To escape transmitted characters, use the -.Cm escape -option. -.It Cm auth -Require the peer to authenticate itself before allowing network -packets to be sent or received. -.It Cm call Ar name -Read options from the file -.Pa /etc/ppp/peers/ Ns Ar name . -This file may contain privileged options, such as -.Cm noauth , -even if -.Nm -is not being run by root. -The -.Ar name -string may not begin with -.Dq / -or include -.Dq .. -as a pathname component. -The format of the options file is described below. -.It Cm connect Ar script -Use the executable or shell command specified by -.Ar script -to set up the serial line. -This script would typically use the -.Xr chat 8 -program to dial the modem and start the remote ppp session. -This option is privileged if the -.Cm noauth -option is used. -.It Cm connect-max-attempts Ar number -Attempt dial-out connection to remote system no more than specified -.Ar number -of times. -The default is 1. -If the connection is not made, -.Nm -will exit. -Requires that -.Cm persist -has been specified. -.It Cm crtscts -Use hardware flow control (i.e. RTS/CTS) to control the flow of data -on the serial port. -If neither the -.Cm crtscts -nor the -.Cm nocrtscts -option is given, the hardware flow control setting -for the serial port is left unchanged. -.It Cm 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 -.Cm nodefaultroute -option has been specified. -.It Cm disconnect Ar script -Run the executable or shell command specified by -.Ar script -after -.Nm -has terminated the link. -This script 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. -This option is privileged if the -.Cm noauth -option is used. -.It Cm escape Ar xx,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 -.Cm escape -option, unlike the -.Cm asyncmap -option which only allows control characters to be specified. -The characters which may not be escaped are those -with hex values 0x20 to 0x3f or 0x5e. -.It Cm file Ar name -Read options from file -.Ar name -(the format is described below). -The file must be readable by the user who has invoked -.Nm . -.It Cm lock -Specifies that -.Nm -should create a UUCP-style lock file for the -serial device to ensure exclusive access to the device. -.It Cm mru Ar size -Set the Maximum Receive Unit (MRU) value to -.Ar size . -.Nm -will ask the peer to send packets of no more than -.Ar size -bytes. -The minimum MRU value is 128. -The default MRU value is 1500. -A value of 296 is recommended for slow links -(40 bytes for TCP/IP header + 256 bytes of data). -.It Cm mtu Ar size -Set the Maximum Transmit Unit (MTU) value to -.Ar size . -Unless the peer requests a smaller value via MRU negotiation, -.Nm -will request that the kernel networking code send data packets of no more -than -.Ar size -bytes through the PPP network interface. -.It Cm passive -Enables the -.Dq passive -option in the LCP. -With this option, -.Nm -will attempt to initiate a connection; -if no reply is received from the peer, -.Nm -will then just wait passively for a valid LCP packet from -the peer, instead of exiting, as it would without this option. -.El -.Ss OPTIONS -.Bl -ohang -offset indent -.It Ar local_IP_address Ns Li : Ns Ar remote_IP_address -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 -.Cm noipdefault -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, -.Nm -will not accept a different value from the peer in the IPCP -negotiation, unless the -.Cm ipcp-accept-local -and/or -.Cm ipcp-accept-remote -options are given, respectively. -.It Cm bsdcomp Ar nr Ns Li , Ns Ar nt -Request that the peer compress packets that it sends, using the -BSD-Compress scheme, with a maximum code size of -.Ar nr -bits, and -agree to compress packets sent to the peer with a maximum code size of -.Ar nt -bits. -If -.Ar nt -is not specified, it defaults to the value given for -.Ar nr . -Values in the range 9 to 15 may be used for -.Ar nr -and -.Ar nt ; -larger values give better compression but -consume more kernel memory for compression dictionaries. -Alternatively, a value of 0 for -.Ar nr -or -.Ar nt -disables compression in the corresponding direction. -Use -.Cm nobsdcomp -or -.Cm bsdcomp Li 0 -to disable BSD-Compress compression entirely. -.It Cm chap-interval Ar number -If this option is given, -.Nm -will rechallenge the peer every -.Ar number -seconds. -.It Cm chap-max-challenge Ar number -Set the maximum number of CHAP challenge transmissions to -.Ar number . -The default is 10. -.It Cm chap-restart Ar number -Set the CHAP restart interval (retransmission timeout for challenges) -to -.Ar number -seconds. -The default is 3. -.It Cm debug -Enables connection debugging facilities. -If this option is given, -.Nm -will log the contents of all -control packets sent or received in a readable form. -The packets are logged through syslog with facility -.Sy daemon -and level -.Sy debug . -This information can be directed to a file by setting up -.Pa /etc/syslog.conf -appropriately (see -.Xr syslog.conf 5 ) . -.It Cm default-asyncmap -Disable asyncmap negotiation, forcing all control characters to be -escaped for both the transmit and the receive direction. -.It Cm default-mru -Disable Maximum Receive Unit (MRU) negotiation. -With this option, -.Nm -will use the default MRU value of 1500 bytes for both the -transmit and receive direction. -.It Cm deflate Ar nr Ns Li , Ns Ar nt -Request that the peer compress packets that it sends, using the -Deflate scheme, with a maximum window size of -.Li 2** Ns Ar nr -bytes, and agree to compress packets sent to the peer with a -maximum window size of -.Li 2** Ns Ar nt -bytes. -If -.Ar nt -is not specified, it defaults to the value given for -.Ar nr . -Values in the range 8 to 15 may be used for -.Ar nr -and -.Ar nt ; -larger values give better compression but -consume more kernel memory for compression dictionaries. -Alternatively, a value of 0 for -.Ar nr -or -.Ar nt -disables compression in the corresponding direction. -Use -.Cm nodeflate -or -.Cm deflate Li 0 -to disable Deflate compression entirely. -Note: -.Nm -requests Deflate compression in preference to BSD-Compress if the peer -can do either. -.It Cm demand -Initiate the link only on demand, i.e. when data traffic is present. -With this option, the remote IP address must be specified by the user -on the command line or in an options file. -.Nm -will initially -configure the interface and enable it for IP traffic without -connecting to the peer. -When traffic is available, -.Nm -will connect to the peer and perform negotiation, authentication, etc. -When this is completed, -.Nm -will commence passing data packets -(i.e. IP packets) across the link. -The -.Cm demand -option implies the -.Cm persist -option. -If this behaviour is not desired, use the -.Cm nopersist -option after the -.Cm demand -option. -The -.Cm idle -and -.Cm holdoff -options are also useful in conjunction with the -.Cm demand -option. -.It Cm domain Ar name -Append the domain name -.Ar name -to the local host name for authentication purposes. -For example, if gethostname() returns the name -.Sq porsche , -but the fully qualified domain name is -.Sq porsche.quotron.com , -you could specify -.Cm domain Li quotron.com . -.Nm -would then use the name -.Sq porsche.quotron.com -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. -.It Cm holdoff Ar number -Specifies how many seconds to wait before re-initiating the link after -it terminates. -This option only has any effect if the -.Cm persist -or -.Cm demand -option is used. -The holdoff period is not applied if -the link was terminated because it was idle. -.It Cm idle Ar number -Specifies that -.Nm -should disconnect if the link is idle for -.Ar number -seconds. -The link is idle when no data packets (i.e. IP packets) are -being sent or received. -If the -.Cm active-filter -option is given, data packets which are rejected by the specified -activity filter also count as the link being idle. -Note: it is not advisable to use this option with the -.Cm persist -option without the -.Cm demand -option. -.It Cm ipcp-accept-local -With this option, -.Nm -will accept the peer's idea of our local IP -address, even if the local IP address was specified in an option. -.It Cm ipcp-accept-remote -With this option, -.Nm -will accept the peer's idea of its (remote) IP -address, even if the remote IP address was specified in an option. -.It Cm ipcp-max-configure Ar number -Set the maximum number of IPCP configure-request transmissions to -.Ar number . -The default is 10. -.It Cm ipcp-max-failure Ar number -Set the maximum number of IPCP configure-NAKs returned before starting -to send configure-Rejects instead to -.Ar number . -The default is 10. -.It Cm ipcp-max-terminate Ar number -Set the maximum number of IPCP terminate-request transmissions to -.Ar number . -The default is 3. -.It Cm ipcp-restart Ar number -Set the IPCP restart interval (retransmission timeout) to -.Ar number -seconds. -The default is 3. -.It Cm ipparam Ar string -Provides an extra parameter to the ip-up and ip-down scripts. -If this option is given, the -.Ar string -supplied is given as the 6th -parameter to those scripts. -.It Cm ipx -Enable the IPXCP and IPX protocols. -This option is presently only supported under Linux, and only if your -kernel has been configured to include IPX support. -.It Cm ipx-network Ar number -Set the IPX network number in the IPXCP configure request frame to -.Ar number , -a hexadecimal number (without a leading 0x). -There is no valid default. -If this option is not specified, the network number is -obtained from the peer. -If the peer does not have the network number, -the IPX protocol will not be started. -.It Cm ipx-node Ar local Ns Li : Ns Ar remote -Set the IPX node numbers. -The two node numbers are separated from each -other with a colon character. -The first number -.Ar local -is the local node number. -The second number -.Ar remote -is the peer's node number. -Each node number is a hexadecimal number, at most 10 digits long. -The node numbers on the ipx-network must be unique. -There is no valid default. -If this option is not specified then the node numbers are -obtained from the peer. -.It Cm ipx-router-name Ar string -Set the name of the router. -This is a string and is sent to the peer -as information data. -.It Cm ipx-routing Ar protocol -Set the routing protocol to be received by this option. -More than one instance of -.Cm ipx-routing -may be specified. -The values may be 0 for NONE, 2 for IRIP/SAP, and 4 for NLSP. -The NONE option may be specified as the only instance of ipx-routing. -.It Cm ipxcp-accept-local -Accept the peer's NAK for the node number specified in the ipx-node -option. -If a node number was specified, and non-zero, the default is -to insist that the value be used. -If you include this option then you -will permit the peer to override the entry of the node number. -.It Cm ipxcp-accept-network -Accept the peer's NAK for the network number specified in the -ipx-network option. -If a network number was specified, and non-zero, the -default is to insist that the value be used. -If you include this -option then you will permit the peer to override the entry of the node -number. -.It Cm ipxcp-accept-remote -Use the peer's network number specified in the configure request -frame. -If a node number was specified for the peer and this option was -not specified, the peer will be forced to use the value which you have -specified. -.It Cm ipxcp-max-configure Ar number -Set the maximum number of IPXCP configure request frames which the -system will send. -The default is 10. -.It Cm ipxcp-max-failure Ar number -Set the maximum number of IPXCP NAK frames which the local system will -send before it rejects the options. -The default is 3. -.It Cm ipxcp-max-terminate Ar number -Set the maximum number of IPXCP terminate request frames before the -local system considers that the peer is not listening to them. -The default is 3. -.It Cm kdebug Ar level -Enable debugging code in the kernel-level PPP driver. -The argument -.Ar level -is a number which is the sum of the following values: 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 -.Xr syslogd 8 , -to a file as directed in the -.Pa /etc/syslog.conf -configuration file. -.It Cm lcp-echo-failure Ar number -If this option is given, -.Nm -will presume the peer to be dead if -.Ar number -LCP echo-requests are sent without receiving a valid LCP echo-reply. -If this happens, -.Nm -will terminate the connection. -Use of this option requires a non-zero value for the -.Cm lcp-echo-interval -parameter. -This option can be used to enable -.Nm -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. -.It Cm lcp-echo-interval Ar number -If this option is given, -.Nm -will send an LCP echo-request frame to the peer every -.Ar number -seconds. -Normally the peer should respond to -the echo-request by sending an echo-reply. -This option can be used -with the -.Cm lcp-echo-failure -option to detect that the peer is no longer connected. -.It Cm lcp-max-configure Ar number -Set the maximum number of LCP configure-request transmissions to -.Ar number . -The default is 10. -.It Cm lcp-max-failure Ar number -Set the maximum number of LCP configure-NAKs returned before starting -to send configure-Rejects instead to -.Ar number . -The default is 10. -.It Cm lcp-max-terminate Ar number -Set the maximum number of LCP terminate-request transmissions to -.Ar number . -The default is 3. -.It Cm lcp-restart Ar number -Set the LCP restart interval (retransmission timeout) to -.Ar number -seconds. -The default is 3. -.It Cm local -Don't use the modem control lines. -With this option, -.Nm -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. -.It Cm 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 -.Pa /etc/ppp/pap-secrets -file as well as the system password database to be allowed access. -.It Cm maxconnect Ar number -Terminate the connection when it has been available for network -traffic for -.Ar number -seconds (i.e.\& -.Ar number -seconds after the first network control protocol comes up). -.It Cm modem -Use the modem control lines. -This option is the default. -With this option, -.Nm -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 -.Cm crtscts -option. -.It Cm ms-dns Ar address -If -.Nm -is acting as a server for Microsoft Windows clients, this -option allows -.Nm -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. -Note: this option was present in some older versions of -.Nm -under the name -.Cm dns-addr . -.It Cm ms-wins Ar address -If -.Nm -is acting as a server for Microsoft Windows or Samba -clients, this option allows -.Nm -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. -.It Cm name Ar name -Set the name of the local system for authentication purposes to -.Ar name . -This is a privileged option. -With this option, -.Nm -will use lines in the secrets files which have -.Ar name -as the second -field when looking for a secret to use in authenticating the peer. -In addition, unless overridden with the -.Cm user -option, -.Cm name -will be used as the name to send to the peer when authenticating the -local system to the peer. -Note: -.Nm -does not append the domain name to -.Ar name . -.It Cm netmask Ar mask -Set the interface netmask to -.Ar mask , -a 32 bit netmask in decimal dot notation (e.g. 255.255.255.0). -If this option is given, the value -specified is ORed with the default netmask. -The default netmask is chosen based on the negotiated remote IP address; -it is the -appropriate network mask for the class of the remote IP address, ORed -with the netmasks for any non point-to-point network interfaces in the -system which are on the same network. -.It Cm noaccomp -Disable Address/Control compression in both directions (send and -receive). -.It Cm noauth -Do not require the peer to authenticate itself. -This option is privileged if the -.Cm auth -option is specified in -.Pa /etc/ppp/options . -.It Cm nobsdcomp -Disables BSD-Compress compression; -.Nm -will not request or -agree to compress packets using the BSD-Compress scheme. -.It Cm noccp -Disable Compression Control Protocol (CCP) negotiation. -This option -should only be required if the peer is buggy and gets confused by -requests from -.Nm -for CCP negotiation. -.It Cm nocrtscts -Disable hardware flow control (i.e. RTS/CTS) on the serial port. -If neither the -.Cm crtscts -nor the -.Cm nocrtscts -option is given, the hardware flow control setting for the serial -port is left unchanged. -.It Cm nodefaultroute -Disable the -.Cm defaultroute -option. -The system administrator who -wishes to prevent users from creating default routes with -.Nm -can do so by placing this option in the -.Pa /etc/ppp/options -file. -.It Cm nodeflate -Disables Deflate compression; -.Nm -will not request or agree to compress packets using the Deflate scheme. -.It Cm 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, -.Nm -will fork to become a background process. -.It Cm noip -Disable IPCP negotiation and IP communication. -This option should only be required if the peer is buggy and gets -confused by requests from -.Nm -for IPCP negotiation. -.It Cm 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). -.It Cm noipx -Disable the IPXCP and IPX protocols. -This option should only be -required if the peer is buggy and gets confused by requests from -.Nm -for IPXCP negotiation. -.It Cm nomagic -Disable magic number negotiation. -With this option, -.Nm -cannot detect a looped-back line. -This option should only be needed if the peer is buggy. -.It Cm nopcomp -Disable protocol field compression negotiation in both the receive and -the transmit direction. -.It Cm nopersist -Exit once a connection has been made and terminated. -This is the default unless the -.Cm persist -or -.Cm demand -option has been specified. -.It Cm nopredictor1 -Do not accept or agree to Predictor-1 compression. -.It Cm noproxyarp -Disable the -.Cm proxyarp -option. -The system administrator who -wishes to prevent users from creating proxy ARP entries with -.Nm -can do so by placing this option in the -.Pa /etc/ppp/options -file. -.It Cm novj -Disable Van Jacobson style TCP/IP header compression in both the -transmit and the receive direction. -.It Cm novjccomp -Disable the connection-ID compression option in Van Jacobson style -TCP/IP header compression. -With this option, -.Nm -will not omit the connection-ID byte from Van Jacobson compressed -TCP/IP headers, nor ask the peer to do so. -.It Cm papcrypt -Indicates that all secrets in the -.Pa /etc/ppp/pap-secrets -file which are -used for checking the identity of the peer are encrypted, and thus -.Nm -should not accept a password which, before encryption, is -identical to the secret from the -.Pa /etc/ppp/pap-secrets -file. -.It Cm pap-max-authreq Ar number -Set the maximum number of PAP authenticate-request transmissions to -.Ar number . -The default is 10. -.It Cm pap-restart Ar number -Set the PAP restart interval (retransmission timeout) to -.Ar number -seconds. -The default is 3. -.It Cm pap-timeout Ar number -Set the maximum time that -.Nm -will wait for the peer to authenticate itself with PAP to -.Ar number -seconds (0 means no limit). -.It Cm pass-filter Ar filter-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 basic firewall -capability. -The -.Ar filter-expression -syntax is as described for -.Xr tcpdump 1 , -except that qualifiers which are inappropriate for a PPP link, such as -.Cm ether -and -.Cm arp , 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 -.Cm inbound -and -.Cm outbound -qualifiers. -This option is currently only available under -.Nx , -and then only if both the kernel and -.Nm -were compiled with -.Dv PPP_FILTER -defined. -.It Cm persist -Do not exit after a connection is terminated; instead try to reopen -the connection. -.It Cm 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. -.It Cm proxyarp -Add an entry to this system's Address Resolution Protocol (ARP) 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. -.It Cm remotename Ar name -Set the assumed name of the remote system for authentication purposes -to -.Ar name . -.It Cm refuse-chap -With this option, -.Nm -will not agree to authenticate itself to the peer using CHAP. -.It Cm refuse-pap -With this option, -.Nm -will not agree to authenticate itself to the peer using PAP. -.It Cm require-chap -Require the peer to authenticate itself using Challenge -Handshake Authentication Protocol (CHAP) authentication. -.It Cm require-pap -Require the peer to authenticate itself using Password -Authentication Protocol (PAP) authentication. -.It Cm silent -With this option, -.Nm -will not transmit LCP packets to initiate a connection until -a valid LCP packet is received from the peer (as for the -.Sq passive -option with ancient versions of -.Nm ) . -.It Cm 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 -.Cm name -option). -.It Cm user Ar name -Sets the name used for authenticating the local system to the peer to -.Ar name . -.It Cm vj-max-slots Ar number -Sets the number of connection slots to be used by the Van Jacobson -TCP/IP header compression and decompression code to -.Ar number , -which must be between 2 and 16 inclusively. -.It Cm welcome Ar script -Run the executable or shell command specified by -.Ar script -before initiating PPP negotiation, after the connect script -(if any) has completed. -This option is privileged if the -.Cm noauth -option is used. -.It Cm xonxoff -Use software flow control (i.e. XON/XOFF) to control the flow of data on -the serial port. -.El -.Ss SIGNALS -The following signals have the specified effect when sent to -.Nm : -.Bl -tag -width ".Dv SIGINT Ns , Dv SIGTERM" -offset indent -.It Dv SIGINT Ns , Dv SIGTERM -These signals cause -.Nm -to terminate the link (by closing LCP), -restore the serial device settings, and exit. -.It Dv SIGHUP -This signal causes -.Nm -to terminate the link, restore the serial -device settings, and close the serial device. -If the -.Cm persist -or -.Cm demand -option has been specified, -.Nm -will try to reopen the -serial device and start another connection (after the holdoff period). -Otherwise -.Nm -will exit. -If this signal is received during the holdoff period, it causes -.Nm -to end the holdoff period immediately. -.It Dv SIGUSR1 -This signal toggles the state of the -.Cm debug -option. -.It Dv SIGUSR2 -This signal causes -.Nm -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.) -.El -.Ss SECURITY -.Nm -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. -In part this is provided by the -.Pa /etc/ppp/options -file, where the administrator can place options to restrict the ways in which -.Nm -can be used, and in part by the PAP and CHAP secrets files, where the -administrator can restrict the set of IP addresses which individual -users may use. -.Pp -The normal way that -.Nm -should be set up is to have the -.Cm auth -option in the -.Pa /etc/ppp/options -file. -(This may become the default in later releases.) -If users wish to use -.Nm -to dial out to a peer which will refuse to authenticate itself -(such as an internet service provider), the system administrator -should create an options file under -.Pa /etc/ppp/peers -containing the -.Cm noauth -option, the name of the serial port to use, and the -.Cm connect -option (if required), plus any other appropriate options. -In this way, -.Nm -can be set up -to allow non-privileged users to make unauthenticated connections only -to trusted peers. -.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 -.Nm , -either on the command line, in the user's -.Pa ~/.ppprc -file, or in an options file read using the -.Cm file -option. -Privileged options may be used in -.Pa /etc/ppp/options -file or in an options file read using the -.Cm call -option. -If -.Nm -is being run by the root user, privileged options can be used without -restriction. -.Ss 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 -.Sy client -and the other the -.Sy 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. -.Pp -At present, -.Nm -supports two authentication protocols: the Password -Authentication Protocol (PAP) and the Challenge Handshake -Authentication Protocol (CHAP). -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. -.Pp -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. -.Pp -The default behaviour of -.Nm -is to agree to authenticate if -requested, and to not require authentication from the peer. -However, -.Nm -will not agree to authenticate itself with a particular protocol -if it has no secrets which could be used to do so. -.Pp -.Nm -stores secrets for use in authentication in secrets -files ( -.Pa /etc/ppp/pap-secrets -for PAP, -.Pa /etc/ppp/chap-secrets -for CHAP). -Both secrets files have the same format. -The secrets files can contain secrets for -.Nm -to use in authenticating itself to other -systems, as well as secrets for -.Nm -to use when authenticating other systems to itself. -.Pp -Each line in a secrets file contains one secret. -A given secret is -specific to a particular combination of client and server \(em 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. -.Pp -A secrets file is parsed into words as for an 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. -Any following words on the same line are taken to be a list -of acceptable IP addresses for that client, or an -override for -.Sy local:remote -addresses (the same format used on the -command line or in the options file) when on a line that contains a -specific client name (not a wildcard nor empty). -If there are only 3 words -on the line, or if the first word is -.Dq \- , -then all IP addresses are disallowed. -To allow any address, use -.Dq * . -A word starting with -.Dq ! -indicates that the specified address is not acceptable. -An address may be followed by -.Dq / -and a number -.Ar number , -to indicate a whole subnet, i.e. all addresses which have the same -value in the most significant -.Ar number -bits. -Note that case is significant in the client and server names -and in the secret. -.Pp -If the secret starts with an -.Dq @ , -what follows is assumed to be the -name of a file from which to read the secret. -A -.Dq * -as the client or server name matches any name. -When selecting a secret, -.Nm -takes the best match, i.e. the match with the fewest wildcards. -.Pp -Thus a secrets file contains both secrets for use in authenticating -other hosts, plus secrets which we use for authenticating ourselves to -others. -When -.Nm -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 -.Cm domain -option is used. -This default can be overridden with the -.Cm name -option, except when the -.Cm usehostname -option is used. -.Pp -When -.Nm -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 -.Cm user -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 -.Nm -looks for a secret with this name in the first -field and the peer's name in the second field. -.Nm -will know the -name of the peer if CHAP authentication is being used, because the -peer will have sent it in the challenge packet. -However, if PAP is being used, -.Nm -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 -.Cm remotename -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, -.Nm -will use the null string as the peer's name. -.Pp -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 -.Xr crypt 3 -and checked against the secret again. -Thus secrets for authenticating the -peer can be stored in encrypted form if desired. -If the -.Cm papcrypt -option is given, the first (unencrypted) comparison is -omitted, for better security. -.Pp -Furthermore, if the -.Cm login -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 -.Cm login -option, the secret in -.Pa /etc/ppp/pap-secrets -would be -.Dq \&"\&" , -which will match any password supplied by the peer. -This avoids the need to have the same secret in two places. -.Pp -Additional checks are performed when the -.Cm login -option is used. -If the file -.Pa /etc/ppp/ppp.deny -exists, and the user is listed in it, the authentication fails. -If the file -.Pa /etc/ppp/ppp.shells -exists and -the user's normal login shell is not listed, the authentication fails. -.Pp -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, -.Nm -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. -.Pp -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, -.Nm -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. -.Ss ROUTING -When IPCP negotiation is completed successfully, -.Nm -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 -.Cm defaultroute -and/or -.Cm proxyarp -options are sufficient for this, but in some cases -further intervention is required. -The -.Pa /etc/ppp/ip-up -script can be used for this. -.Pp -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 -.Cm defaultroute -option causes -.Nm -to create such a default route when IPCP comes up, and -delete it when the link is terminated. -.Pp -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 -.Cm proxyarp -option causes -.Nm -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, -.Nm -creates a -permanent, published ARP entry with the IP address of the remote host -and the hardware address of the network interface found. -.Pp -When the -.Cm demand -option is used, the interface IP addresses have -already been set at the point when IPCP comes up. -If -.Nm -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), -.Nm -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 ENVIRONMENT -The environment variables that -.Nm -sets are: -.Bl -tag -width "PEERNAME" -.It Ev DEVICE -The name of the serial tty device being used. -.It Ev IFNAME -The name of the network interface being used. -.It Ev IPLOCAL -The IP address for the local end of the link. -This is only set when IPCP has come up. -.It Ev IPREMOTE -The IP address for the remote end of the link. -This is only set when IPCP has come up. -.It Ev PEERNAME -The authenticated name of the peer. -This is only set if the peer authenticates itself. -.It Ev SPEED -The baud rate of the tty device. -.It Ev UID -The real user-id of the user who invoked -.Nm . -.El -.Sh FILES -.Nm -reads options from the files -.Pa /etc/ppp/options , -.Pa ~/.ppprc -and -.Pa /etc/ppp/options. Ns Ar tty_name -(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 -.Pa options. Ns Ar tty_name -file is read.) -.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 (\\) quotes the following character. -A hash (#) starts a comment, which continues until the end of the line. -There is no restriction on using the -.Cm file -or -.Cm call -options within an options file. -.Bl -tag -width ".Pa /usr/share/examples/pppd/" -.It Pa /var/run/ppp Ns Ar unit Ns \&.pid -Process-ID for -.Nm -process on ppp interface -.Ar unit . -.It Pa /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. -.Nm -will log a warning if this is not the case. -.It Pa /etc/ppp/chap-secrets -Names, secrets and IP addresses for CHAP authentication. -As for -.Pa /etc/ppp/pap-secrets , -this file should be owned by root and not -readable or writable by any other user. -.Nm -will log a warning if this is not the case. -.It Pa /etc/ppp/options -System default options for -.Nm , -read before user default options or -command-line options. -.It Pa ~/.ppprc -User default options, read before -.Pa /etc/ppp/options. Ns Ar tty_name . -.It Pa /etc/ppp/options. Ns Ar tty_name -System default options for the serial port being used, read after -.Pa ~/.ppprc . -In forming the -.Ar tty_name -part of this filename, an initial -.Dq /dev/ -is stripped from the port name (if present), and any slashes in the -remaining part are converted to dots. -.It Pa /etc/ppp/peers -A directory containing options files which may contain privileged -options, even if -.Nm -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. -.It Pa /etc/ppp/ppp.deny -Lists users who may not use the system password PAP authentication. -.It Pa /etc/ppp/ppp.shells -Lists user shells which are approved for system password PAP authentication -logins. -.It Pa /usr/share/examples/pppd/ -Sample -.Nm -configuration files. -.El -.Pp -.Nm -also 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. -.Nm -does not wait for the scripts to finish. -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. -.Nm -runs the scripts with -standard input, output and error redirected to -.Pa /dev/null , -and with an -environment that is empty except for some environment variables that -give information about the link. -.Nm -invokes the following scripts, if they exist. -It is not an error if they don't exist. -.Bl -tag -width ".Pa /etc/ppp/auth-down" -.It Pa /etc/ppp/auth-up -A program or script which is executed after the remote system -successfully authenticates itself. -It is executed with the following parameters: -.Pp -.Sy iface-name peer-name user-name tty-dev speed -.Pp -Note that this script is not executed if the peer doesn't authenticate -itself, for example when the -.Cm noauth -option is used. -.It Pa /etc/ppp/auth-down -A program or script which is executed when the link goes down, if -.Pa /etc/ppp/auth-up -was previously executed. -It is executed in the same manner with the same parameters as -.Pa /etc/ppp/auth-up . -.It Pa /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 following parameters: -.Pp -.Sy iface-name tty-dev speed local-IP remote-IP ipparam -.It Pa /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 -.Pa /etc/ppp/ip-up -script. -It is invoked in the same manner and with the same parameters. -.It Pa /etc/ppp/ipx-up -A program or script which is executed when the link is available for -sending and receiving IPX packets (that is, IPXCP has come up). -It is executed with the following parameters: -.Pp -.Sy iface-name tty-dev speed network-number -.Sy local-IPX-node-address remote-IPX-node-address -.Sy local-IPX-routing-proto remote-IPX-routing-proto -.Sy local-IPX-router-name remote-IPX-router-name -.Sy ipparam pppd-pid -.Pp -The local-IPX-routing-protocol and remote-IPX-routing-protocol field -may be one of the following: -.Bl -hang -.It Dq NONE -to indicate that there is no routing protocol -.It Dq RIP -to indicate that RIP/SAP should be used -.It Dq NLSP -to indicate that Novell NLSP should be used -.It Dq RIP NLSP -to indicate that both RIP/SAP and NLSP should be used -.El -.It Pa /etc/ppp/ipx-down -A program or script which is executed when the link is no longer -available for sending and receiving IPX packets. -This script can be used for undoing the effects of the -.Pa /etc/ppp/ipx-up -script. -It is invoked in the same manner and with the same parameters. -.El -.Sh EXAMPLES -The following examples assume that the -.Pa /etc/ppp/options -file contains the -.Cm auth -option (as in the default -.Pa /etc/ppp/options -file in the ppp distribution). -.Pp -Probably the most common use of -.Nm -is to dial out to an ISP. -This can be done with a command such as -.Bd -literal -offset indent -# pppd call isp -.Ed -.Pp -where the -.Pa /etc/ppp/peers/isp -file is set up by the system -administrator to contain something like this: -.Bd -literal -offset indent -ttyS0 19200 crtscts -connect '/usr/sbin/chat -v -f /etc/ppp/chat-isp' -noauth -.Ed -.Pp -In this example, we are using chat to dial the ISP's modem and go -through any logon sequence required. -The -.Pa /etc/ppp/chat-isp -file contains the script used by chat; it could for example contain -something like this: -.Bd -literal -offset indent -ABORT "NO CARRIER" -ABORT "NO DIALTONE" -ABORT "ERROR" -ABORT "NO ANSWER" -ABORT "BUSY" -ABORT "Username/Password Incorrect" -"" "at" -OK "at&d0&c1" -OK "atdt2468135" -"name:" "^Umyuserid" -"word:" "\\qmypassword" -"ispts" "\\q^Uppp" -"~-^Uppp-~" -.Ed -.Pp -See the -.Xr chat 8 -man page for details of chat scripts. -.Pp -.Nm -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 -.Nm -(installed setuid-root) with a command such as -.Bd -literal -offset indent -# pppd proxyarp -.Ed -.Pp -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 -.Pa /etc/ppp/pap-secrets -or -.Pa /etc/ppp/chap-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 -.Sy joespc -which is to be allowed to dial in to the machine called -.Sy server -and use the IP address -.Sy joespc.my.net , -you would add an entry like this to -.Pa /etc/ppp/pap-secrets -or -.Pa /etc/ppp/chap-secrets : -.Bd -literal -offset indent -joespc server "joe's secret" joespc.my.net -.Ed -.Pp -Alternatively, you can create a username called (for example) -.Sy ppp , -whose login shell is -.Nm -and whose home directory is -.Pa /etc/ppp . -Options to be used when -.Nm -is run this way can be put in -.Pa /etc/ppp/.ppprc . -.Pp -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 -.Cm asyncmap Li a0000 . -If the path includes a telnet, you probably should escape ^] as well -.Pq Cm asyncmap Li 200a0000 . -If the path includes an rlogin, you will need to use the -.Cm escape Li ff -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 -Messages are sent to the syslog daemon using facility -.Dv LOG_DAEMON . -(This can be overridden by recompiling -.Nm -with the macro -.Dv LOG_PPP -defined as the desired facility.) -In order to see the error and debug messages, you will need to edit your -.Pa /etc/syslog.conf -file to direct the messages to the desired output device or file. -.Pp -The -.Cm debug -option causes the contents of all control packets sent -or received to be logged, that is, all LCP, PAP, CHAP 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 -.Cm debug -option also causes other debugging messages to be logged. -.Pp -Debugging can also be enabled or disabled by sending a -.Dv SIGUSR1 -signal to the -.Nm -process. -This signal acts as a toggle. -.Sh SEE ALSO -.Xr tcpdump 1 , -.Xr crypt 3 , -.Xr syslog.conf 5 , -.Xr chat 8 , -.Xr ppp 8 , -.Xr syslogd 8 -.Sh STANDARDS -.Rs -.%A V. Jacobson -.%D February 1990 -.%R RFC 1144 -.%T Compressing TCP/IP headers for low-speed serial links -.Re -.Pp -.Rs -.%A R. Rivest -.%D April 1992 -.%R RFC 1321 -.%T The MD5 Message-Digest Algorithm -.Re -.Pp -.Rs -.%A G. McGregor -.%D May 1992 -.%R RFC 1332 -.%T PPP Internet Protocol Control Protocol (IPCP) -.Re -.Pp -.Rs -.%A B. Lloyd -.%A W.A. Simpson -.%D October 1992 -.%R RFC 1334 -.%T PPP authentication protocols -.Re -.Pp -.Rs -.%A W.A. Simpson -.%D July 1994 -.%R RFC 1661 -.%T The Point-to-Point Protocol (PPP) -.Re -.Pp -.Rs -.%A W.A. Simpson -.%D July 1994 -.%R RFC 1662 -.%T PPP in HDLC-like Framing -.Re -.Sh AUTHORS -.An -nosplit -.Nm -was written by -.An Paul Mackerras Aq Mt Paul.Mackerras@cs.anu.edu.au , -based on earlier work by -.An Drew Perkins , -.An Brad Clements , -.An Karl Fox , -.An Greg Christy , -and -.An Brad Parker . diff --git a/usr.sbin/pppd/pppd.h b/usr.sbin/pppd/pppd.h deleted file mode 100644 index 6764df7e82..0000000000 --- a/usr.sbin/pppd/pppd.h +++ /dev/null @@ -1,494 +0,0 @@ -/* - * pppd.h - PPP daemon global declarations. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/pppd.h,v 1.13 1999/08/28 01:19:08 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/pppd.h,v 1.4 2003/11/03 19:31:40 eirikn Exp $ - */ - -/* - * TODO: - */ - -#ifndef __PPPD_H__ -#define __PPPD_H__ - -#include /* for FILE */ -#include /* for MAXPATHLEN and BSD4_4, if defined */ -#include /* for u_int32_t, if defined */ -#include /* for struct timeval */ -#include - -#if __STDC__ -#include -#define __V(x) x -#else -#include -#define __V(x) (va_alist) va_dcl -#define const -#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 */ - -/* - * Global variables. - */ - -extern int hungup; /* Physical layer has disconnected */ -extern int ifunit; /* Interface unit number */ -extern char ifname[]; /* Interface name */ -extern int ttyfd; /* Serial device file descriptor */ -extern char hostname[]; /* Our hostname */ -extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ -extern int phase; /* Current state of link - see values below */ -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 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 */ - -/* - * 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 int crtscts; /* Use hardware flow control */ -extern int modem; /* Use modem control lines */ -extern int inspeed; /* Input/Output speed requested */ -extern u_int32_t netmask; /* IP netmask to set on interface */ -extern int lockflag; /* Create lock file to lock the serial dev */ -extern int nodetach; /* Don't detach from controlling tty */ -extern char *connector; /* Script to establish physical link */ -extern char *disconnector; /* Script to disestablish physical link */ -extern char *welcomer; /* Script to welcome client after connection */ -extern int max_con_attempts;/* Maximum number of times to try dialing */ -extern int maxconnect; /* Maximum connect time (seconds) */ -extern char user[]; /* Our name for authenticating ourselves */ -extern char passwd[]; /* Password for PAP */ -extern int auth_required; /* Peer is required to authenticate */ -extern int proxyarp; /* Set up proxy ARP entry for peer */ -extern int persist; /* Reopen link after it goes down */ -extern int uselogin; /* Use /etc/passwd for checking PAP */ -extern int lcp_echo_interval; /* Interval between LCP echo-requests */ -extern int lcp_echo_fails; /* Tolerance to unanswered echo-requests */ -extern char our_name[]; /* Our name for authentication purposes */ -extern char remote_name[]; /* Peer's name for authentication */ -extern int explicit_remote;/* remote_name specified with remotename opt */ -extern int usehostname; /* Use hostname for our_name */ -extern int disable_defaultip; /* Don't use hostname for default IP adrs */ -extern int demand; /* Do dial-on-demand */ -extern char *ipparam; /* Extra parameter for ip up/down scripts */ -extern int cryptpap; /* Others' PAP passwords are encrypted */ -extern int idle_time_limit;/* Shut down link if idle for this long */ -extern int holdoff; /* Dead time before restarting */ -extern int refuse_pap; /* Don't wanna auth. ourselves with PAP */ -extern int refuse_chap; /* Don't wanna auth. ourselves with CHAP */ -#ifdef PPP_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 MSLANMAN -extern int ms_lanman; /* Nonzero if use LanMan password instead of NT */ - /* Has meaning only with MS-CHAP challenges */ -#endif - -/* - * Values for phase. - */ -#define PHASE_DEAD 0 -#define PHASE_INITIALIZE 1 -#define PHASE_DORMANT 2 -#define PHASE_ESTABLISH 3 -#define PHASE_AUTHENTICATE 4 -#define PHASE_CALLBACK 5 -#define PHASE_NETWORK 6 -#define PHASE_TERMINATE 7 -#define PHASE_HOLDOFF 8 - -/* - * The following struct gives the addresses of procedures to call - * for a particular protocol. - */ -struct protent { - u_short protocol; /* PPP protocol number */ - /* Initialization procedure */ - void (*init)(int unit); - /* Process a received packet */ - void (*input)(int unit, u_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)(u_char *pkt, int len, - void (*printer)(void *, char *, ...), - void *arg); - /* Process a received data packet */ - void (*datainput)(int unit, u_char *pkt, int len); - int enabled_flag; /* 0 iff protocol is disabled */ - char *name; /* Text name of protocol */ - /* 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)(u_char *pkt, int len); -}; - -/* Table of pointers to supported protocols */ -extern struct protent *protocols[]; - -/* - * Prototypes. - */ - -/* Procedures exported from main.c. */ -void detach(void); /* Detach from controlling tty */ -void die(int); /* Cleanup and exit */ -void quit(void); /* like die(1) */ -void novm(char *); /* Say we ran out of memory, and die */ -void timeout(void (*func)(void *), void *arg, int t); - /* Call func(arg) after t seconds */ -void untimeout(void (*func)(void *), void *arg); - /* Cancel call to func(arg) */ -int run_program(char *prog, char **args, int must_exist); - /* Run program prog with args in child */ -void demuxprotrej(int, int); - /* Demultiplex a Protocol-Reject */ -void format_packet(u_char *, int, void (*) (void *, char *, ...), - void *); /* Format a packet in human-readable form */ -void log_packet(u_char *, int, char *, int); - /* Format a packet and log it with syslog */ -void print_string(char *, int, void (*) (void *, char *, ...), - void *); /* Format a string for output */ -int fmtmsg(char *, int, char *, ...); /* sprintf++ */ -int vfmtmsg(char *, int, char *, va_list); /* vsprintf++ */ -void script_setenv(char *, char *); /* set script env var */ -void script_unsetenv(char *); /* unset script env var */ - -/* Procedures exported from auth.c */ -void link_required(int); /* we are starting to use the link */ -void link_terminated(int); /* we are finished with the link */ -void link_down(int); /* the LCP layer has left the Opened state */ -void link_established(int); /* the link is up; authenticate now */ -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, char *, int); - /* peer successfully authenticated itself */ -void auth_withpeer_fail(int, int); - /* we failed to authenticate ourselves */ -void auth_withpeer_success(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 **, int *); - /* Check peer-supplied username/password */ -int get_secret(int, char *, char *, char *, int *, int); - /* get "secret" for chap */ -int auth_ip_addr(int, u_int32_t); - /* check if IP address is authorized */ -int bad_ip_adrs(u_int32_t); - /* check if IP address is unreasonable */ -void check_access(FILE *, char *); - /* check permissions on secrets file */ - -/* 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); /* process frame from loopback */ - -/* Procedures exported from sys-*.c */ -void sys_init(void); /* Do system-dependent initialization */ -void sys_cleanup(void); /* Restore system state before exiting */ -void sys_check_options(void); /* Check options specified */ -void sys_close(void); /* Clean up in a child before execing */ -int ppp_available(void); /* Test whether ppp kernel support exists */ -void open_ppp_loopback(void); /* Open loopback for demand-dialling */ -void establish_ppp(int); /* Turn serial port into a ppp interface */ -void restore_loop(void); /* Transfer ppp unit back to loopback */ -void disestablish_ppp(int); /* Restore port to normal operation */ -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, u_char *, int); /* Output a PPP packet */ -void wait_input(struct timeval *); - /* Wait for input, with timeout */ -void wait_loop_output(struct timeval *); - /* Wait for pkt from loopback, with timeout */ -void wait_time(struct timeval *); /* Wait for given length of time */ -int read_packet(u_char *); /* Read PPP packet */ -int get_loop_output(void); /* Read pkts from loopback */ -void ppp_send_config(int, int, u_int32_t, int, int); - /* Configure i/f transmit parameters */ -void ppp_set_xaccm(int, ext_accm); - /* Set extended transmit ACCM */ -void ppp_recv_config(int, int, u_int32_t, int, int); - /* Configure i/f receive parameters */ -int ccp_test(int, u_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 sifvjcomp(int, int, int, int); - /* Configure VJ TCP header compression */ -int sifup(int); /* Configure i/f up (for IP) */ -int sifnpmode(int u, int proto, enum NPmode mode); - /* Set mode for handling packets for proto */ -int sifdown(int); /* Configure i/f down (for IP) */ -int sifaddr(int, u_int32_t, u_int32_t, u_int32_t); - /* Configure IP addresses for i/f */ -int cifaddr(int, u_int32_t, u_int32_t); - /* Reset i/f IP addresses */ -int sifdefaultroute(int, u_int32_t, u_int32_t); - /* Create default route through i/f */ -int cifdefaultroute(int, u_int32_t, u_int32_t); - /* Delete default route through i/f */ -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 */ -void unlock(void); /* Delete previously-created lock file */ -int daemon(int, int); /* Detach us from terminal session */ -void logwtmp(const char *, const char *, const char *); - /* Write entry to wtmp file */ -int get_host_seed(void); /* Get host-dependent random number seed */ -#ifdef PPP_FILTER -int set_filters(struct bpf_program *pass, struct bpf_program *active); - /* Set filter programs in kernel */ -#endif - -/* Procedures exported from options.c */ -int parse_args(int argc, char **argv); - /* Parse options from arguments given */ -void usage(void); /* Print a usage message */ -int options_from_file(char *filename, int must_exist, int check_prot, - int privileged); - /* Parse options from an options file */ -int options_from_user(void); /* Parse options from user's .ppprc */ -int options_for_tty(void); /* Parse options from /etc/ppp/options.tty */ -void scan_args(int argc, char **argv); - /* Look for tty name in command-line args */ -int getword(FILE *f, char *word, int *newlinep, char *filename); - /* Read a word from a file */ -void option_error(char *fmt, ...); - /* Print an error message about an option */ -int setipaddr(char *); /* set IP addresses */ - - -/* - * This structure is used to store information about certain - * options, such as where the option value came from (/etc/ppp/options, - * command line, etc.) and whether it came from a privileged source. - */ - -struct option_info { - int priv; /* was value set by sysadmin? */ - char *source; /* where option came from */ -}; - -extern struct option_info auth_req_info; -extern struct option_info connector_info; -extern struct option_info disconnector_info; -extern struct option_info welcomer_info; -extern struct option_info devnam_info; - -/* - * 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 u_char *. - */ -#define GETCHAR(c, cp) { \ - (c) = *(cp)++; \ -} -#define PUTCHAR(c, cp) { \ - *(cp)++ = (u_char) (c); \ -} - - -#define GETSHORT(s, cp) { \ - (s) = *(cp)++ << 8; \ - (s) |= *(cp)++; \ -} -#define PUTSHORT(s, cp) { \ - *(cp)++ = (u_char) ((s) >> 8); \ - *(cp)++ = (u_char) (s); \ -} - -#define GETLONG(l, cp) { \ - (l) = *(cp)++ << 8; \ - (l) |= *(cp)++; (l) <<= 8; \ - (l) |= *(cp)++; (l) <<= 8; \ - (l) |= *(cp)++; \ -} -#define PUTLONG(l, cp) { \ - *(cp)++ = (u_char) ((l) >> 24); \ - *(cp)++ = (u_char) ((l) >> 16); \ - *(cp)++ = (u_char) ((l) >> 8); \ - *(cp)++ = (u_char) (l); \ -} - -#define INCPTR(n, cp) ((cp) += (n)) -#define DECPTR(n, cp) ((cp) -= (n)) - -#undef FALSE -#define FALSE 0 -#undef TRUE -#define TRUE 1 - -/* - * System dependent definitions for user-level 4.3BSD UNIX implementation. - */ - -#define DEMUXPROTREJ(u, p) demuxprotrej(u, p) - -#define TIMEOUT(r, f, t) timeout((r), (f), (t)) -#define UNTIMEOUT(r, f) untimeout((r), (f)) - -#define BCOPY(s, d, l) memcpy(d, s, l) -#define BZERO(s, n) memset(s, 0, n) -#define EXIT(u) quit() - -#define PRINTMSG(m, l) { m[l] = '\0'; syslog(LOG_INFO, "Remote message: %s", m); } - -/* - * MAKEHEADER - Add Header fields to a packet. - */ -#define MAKEHEADER(p, t) { \ - PUTCHAR(PPP_ALLSTATIONS, p); \ - PUTCHAR(PPP_UI, p); \ - PUTSHORT(t, p); } - - -#ifdef DEBUGALL -#define DEBUGMAIN 1 -#define DEBUGFSM 1 -#define DEBUGLCP 1 -#define DEBUGIPCP 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) -#define LOG_PPP LOG_LOCAL2 -#else -#define LOG_PPP LOG_DAEMON -#endif -#endif /* LOG_PPP */ - -#ifdef DEBUGMAIN -#define MAINDEBUG(x) if (debug) syslog x -#else -#define MAINDEBUG(x) -#endif - -#ifdef DEBUGSYS -#define SYSDEBUG(x) if (debug) syslog x -#else -#define SYSDEBUG(x) -#endif - -#ifdef DEBUGFSM -#define FSMDEBUG(x) if (debug) syslog x -#else -#define FSMDEBUG(x) -#endif - -#ifdef DEBUGLCP -#define LCPDEBUG(x) if (debug) syslog x -#else -#define LCPDEBUG(x) -#endif - -#ifdef DEBUGIPCP -#define IPCPDEBUG(x) if (debug) syslog x -#else -#define IPCPDEBUG(x) -#endif - -#ifdef DEBUGUPAP -#define UPAPDEBUG(x) if (debug) syslog x -#else -#define UPAPDEBUG(x) -#endif - -#ifdef DEBUGCHAP -#define CHAPDEBUG(x) if (debug) syslog x -#else -#define CHAPDEBUG(x) -#endif - -#ifdef DEBUGIPXCP -#define IPXCPDEBUG(x) if (debug) syslog x -#else -#define IPXCPDEBUG(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 - -#endif /* __PPP_H__ */ diff --git a/usr.sbin/pppd/sys-bsd.c b/usr.sbin/pppd/sys-bsd.c deleted file mode 100644 index 5e15237395..0000000000 --- a/usr.sbin/pppd/sys-bsd.c +++ /dev/null @@ -1,1432 +0,0 @@ -/* - * sys-bsd.c - System-dependent procedures for setting up - * PPP interfaces on bsd-4.4-ish systems (including 386BSD, NetBSD, etc.) - * - * Copyright (c) 1989 Carnegie Mellon University. - * Copyright (c) 1995 The Australian National University. - * 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 Carnegie Mellon University and The Australian National University. - * The names of the Universities 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. - * - * $FreeBSD: src/usr.sbin/pppd/sys-bsd.c,v 1.17.2.1 2002/09/17 16:53:55 nectar Exp $ - */ - -/* $NetBSD: sys-bsd.c,v 1.1.1.3 1997/09/26 18:53:04 christos Exp $ */ - -/* - * TODO: - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef NetBSD1_2 -#include -#endif -#ifdef PPP_FILTER -#include -#endif - -#include -#include -#include -#include -#include -#include - -#if RTM_VERSION >= 3 -#include -#if defined(NetBSD) && (NetBSD >= 199703) -#include -#else /* NetBSD 1.2D or later */ -#ifdef __DragonFly__ -#include -#else -#include -#endif -#endif -#endif - -#include "pppd.h" -#include "fsm.h" -#include "ipcp.h" - -static int initdisc = -1; /* Initial TTY discipline for ppp_fd */ -static int initfdflags = -1; /* Initial file descriptor flags for ppp_fd */ -static int ppp_fd = -1; /* fd which is set to PPP discipline */ -static int rtm_seq; - -static int restore_term; /* 1 => we've munged the terminal */ -static struct termios inittermios; /* Initial TTY termios */ -static struct winsize wsinfo; /* Initial window size info */ - -static char *lock_file; /* name of lock file created */ - -static int loop_slave = -1; -static int loop_master; -static char loop_name[20]; - -static unsigned char inbuf[512]; /* buffer for chars read from loopback */ - -static int sockfd; /* socket for doing interface ioctls */ - -static int if_is_up; /* the interface is currently up */ -static u_int32_t ifaddrs[2]; /* local and remote addresses we set */ -static u_int32_t default_route_gateway; /* gateway addr for default route */ -static u_int32_t proxy_arp_addr; /* remote addr for proxy arp */ - -/* Prototypes for procedures local to this file. */ -static int dodefaultroute(u_int32_t, int); -static int get_ether_addr(u_int32_t, struct sockaddr_dl *); - - -/* - * sys_init - System-dependent initialization. - */ -void -sys_init(void) -{ - /* Get an internet socket for doing socket ioctl's on. */ - if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - syslog(LOG_ERR, "Couldn't create IP socket: %m"); - die(1); - } -} - -/* - * 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) -{ - struct ifreq ifr; - - if (if_is_up) { - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) >= 0 - && ((ifr.ifr_flags & IFF_UP) != 0)) { - ifr.ifr_flags &= ~IFF_UP; - ioctl(sockfd, SIOCSIFFLAGS, &ifr); - } - } - if (ifaddrs[0] != 0) - cifaddr(0, ifaddrs[0], ifaddrs[1]); - if (default_route_gateway) - cifdefaultroute(0, 0, default_route_gateway); - if (proxy_arp_addr) - cifproxyarp(0, proxy_arp_addr); -} - -/* - * sys_close - Clean up in a child process before execing. - */ -void -sys_close(void) -{ - close(sockfd); - if (loop_slave >= 0) { - close(loop_slave); - close(loop_master); - } -} - -/* - * sys_check_options - check the options that the user specified - */ -void -sys_check_options(void) -{ -} - -/* - * ppp_available - check whether the system has any ppp interfaces - * (in fact we check whether we can do an ioctl on ppp0). - */ -int -ppp_available(void) -{ - int s, ok; - struct ifreq ifr; - extern char *no_ppp_msg; - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - return 1; /* can't tell */ - - strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); - ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; - close(s); - - no_ppp_msg = "\ -This system lacks kernel support for PPP. To include PPP support\n\ -in the kernel, please follow the steps detailed in the README.bsd\n\ -file in the ppp-2.2 distribution.\n"; - return ok; -} - -/* - * establish_ppp - Turn the serial port into a ppp interface. - */ -void -establish_ppp(int fd) -{ - int pppdisc = PPPDISC; - int x; - - if (demand) { - /* - * Demand mode - prime the old ppp device to relinquish the unit. - */ - if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) < 0) { - syslog(LOG_ERR, "ioctl(transfer ppp unit): %m"); - die(1); - } - } - - /* - * Save the old line discipline of fd, and set it to PPP. - */ - if (ioctl(fd, TIOCGETD, &initdisc) < 0) { - syslog(LOG_ERR, "ioctl(TIOCGETD): %m"); - die(1); - } - if (ioctl(fd, TIOCSETD, &pppdisc) < 0) { - syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); - die(1); - } - - if (!demand) { - /* - * Find out which interface we were given. - */ - if (ioctl(fd, PPPIOCGUNIT, &ifunit) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m"); - die(1); - } - } else { - /* - * Check that we got the same unit again. - */ - if (ioctl(fd, PPPIOCGUNIT, &x) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m"); - die(1); - } - if (x != ifunit) { - syslog(LOG_ERR, "transfer_ppp failed: wanted unit %d, got %d", - ifunit, x); - die(1); - } - x = TTYDISC; - ioctl(loop_slave, TIOCSETD, &x); - } - - ppp_fd = fd; - - /* - * Enable debug in the driver if requested. - */ - if (kdebugflag) { - if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_WARNING, "ioctl (PPPIOCGFLAGS): %m"); - } else { - x |= (kdebugflag & 0xFF) * SC_DEBUG; - if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) - syslog(LOG_WARNING, "ioctl(PPPIOCSFLAGS): %m"); - } - } - - /* - * Set device for non-blocking reads. - */ - if ((initfdflags = fcntl(fd, F_GETFL)) == -1 - || fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) { - syslog(LOG_WARNING, "Couldn't set device to non-blocking mode: %m"); - } -} - -/* - * restore_loop - reattach the ppp unit to the loopback. - */ -void -restore_loop(void) -{ - int x; - - /* - * Transfer the ppp interface back to the loopback. - */ - if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) < 0) { - syslog(LOG_ERR, "ioctl(transfer ppp unit): %m"); - die(1); - } - x = PPPDISC; - if (ioctl(loop_slave, TIOCSETD, &x) < 0) { - syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); - die(1); - } - - /* - * Check that we got the same unit again. - */ - if (ioctl(loop_slave, PPPIOCGUNIT, &x) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m"); - die(1); - } - if (x != ifunit) { - syslog(LOG_ERR, "transfer_ppp failed: wanted unit %d, got %d", - ifunit, x); - die(1); - } - ppp_fd = loop_slave; -} - - -/* - * disestablish_ppp - Restore the serial port to normal operation. - * This shouldn't call die() because it's called from die(). - */ -void -disestablish_ppp(int fd) -{ - /* Reset non-blocking mode on fd. */ - if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) < 0) - syslog(LOG_WARNING, "Couldn't restore device fd flags: %m"); - initfdflags = -1; - - /* Restore old line discipline. */ - if (initdisc >= 0 && ioctl(fd, TIOCSETD, &initdisc) < 0) - syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); - initdisc = -1; - - if (fd == ppp_fd) - ppp_fd = -1; -} - -/* - * Check whether the link seems not to be 8-bit clean. - */ -void -clean_check(void) -{ - int x; - char *s; - - 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 = "bit 7 set to 1"; - break; - case SC_RCV_B7_1: - s = "bit 7 set to 0"; - break; - case SC_RCV_EVNP: - s = "odd parity"; - break; - case SC_RCV_ODDP: - s = "even parity"; - break; - } - if (s != NULL) { - syslog(LOG_WARNING, "Serial link is not 8-bit clean:"); - syslog(LOG_WARNING, "All received characters had %s", s); - } - } -} - -/* - * 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. - * - * For *BSD, we assume that speed_t values numerically equal bits/second. - */ -void -set_up_tty(int fd, int local) -{ - struct termios tios; - - if (tcgetattr(fd, &tios) < 0) { - syslog(LOG_ERR, "tcgetattr: %m"); - die(1); - } - - if (!restore_term) { - inittermios = tios; - ioctl(fd, TIOCGWINSZ, &wsinfo); - } - - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); - if (crtscts > 0 && !local) - tios.c_cflag |= CRTSCTS; - else if (crtscts < 0) - tios.c_cflag &= ~CRTSCTS; - - 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 */ - } - - if (inspeed) { - cfsetospeed(&tios, inspeed); - cfsetispeed(&tios, inspeed); - } else { - inspeed = cfgetospeed(&tios); - /* - * We can't proceed if the serial port speed is 0, - * since that implies that the serial port is disabled. - */ - if (inspeed == 0) { - syslog(LOG_ERR, "Baud rate for %s is 0; need explicit baud rate", - devnam); - die(1); - } - } - baud_rate = inspeed; - - if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { - syslog(LOG_ERR, "tcsetattr: %m"); - die(1); - } - - 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 (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0) - if (errno != ENXIO) - syslog(LOG_WARNING, "tcsetattr: %m"); - 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_ppp_loopback - open the device we use for getting - * packets in demand mode, and connect it to a ppp interface. - * Here we use a pty. - */ -void -open_ppp_loopback(void) -{ - int flags; - struct termios tios; - int pppdisc = PPPDISC; - - if (openpty(&loop_master, &loop_slave, loop_name, NULL, NULL) < 0) { - syslog(LOG_ERR, "No free pty for loopback"); - die(1); - } - SYSDEBUG((LOG_DEBUG, "using %s for loopback", loop_name)); - - if (tcgetattr(loop_slave, &tios) == 0) { - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); - tios.c_cflag |= CS8 | CREAD; - tios.c_iflag = IGNPAR; - tios.c_oflag = 0; - tios.c_lflag = 0; - if (tcsetattr(loop_slave, TCSAFLUSH, &tios) < 0) - syslog(LOG_WARNING, "couldn't set attributes on loopback: %m"); - } - - if ((flags = fcntl(loop_master, F_GETFL)) != -1) - if (fcntl(loop_master, F_SETFL, flags | O_NONBLOCK) == -1) - syslog(LOG_WARNING, "couldn't set loopback to nonblock: %m"); - - ppp_fd = loop_slave; - if (ioctl(ppp_fd, TIOCSETD, &pppdisc) < 0) { - syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); - die(1); - } - - /* - * Find out which interface we were given. - */ - if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m"); - die(1); - } - - /* - * Enable debug in the driver if requested. - */ - if (kdebugflag) { - if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &flags) < 0) { - syslog(LOG_WARNING, "ioctl (PPPIOCGFLAGS): %m"); - } else { - flags |= (kdebugflag & 0xFF) * SC_DEBUG; - if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) - syslog(LOG_WARNING, "ioctl(PPPIOCSFLAGS): %m"); - } - } - -} - - -/* - * output - Output PPP packet. - */ -void -output(int unit, u_char *p, int len) -{ - if (debug) - log_packet(p, len, "sent ", LOG_DEBUG); - - if (write(ttyfd, p, len) < 0) { - if (errno != EIO) - syslog(LOG_ERR, "write: %m"); - } -} - - -/* - * wait_input - wait until there is data available on ttyfd, - * for the length of time specified by *timo (indefinite - * if timo is NULL). - */ -void -wait_input(struct timeval *timo) -{ - fd_set ready; - int n; - - if (ttyfd >= FD_SETSIZE) { - syslog(LOG_ERR, "descriptor too big"); - die(1); - } - FD_ZERO(&ready); - FD_SET(ttyfd, &ready); - n = select(ttyfd+1, &ready, NULL, &ready, timo); - if (n < 0 && errno != EINTR) { - syslog(LOG_ERR, "select: %m"); - die(1); - } -} - - -/* - * 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) -{ - fd_set ready; - int n; - - if (loop_master >= FD_SETSIZE) { - syslog(LOG_ERR, "descriptor too big"); - die(1); - } - FD_ZERO(&ready); - FD_SET(loop_master, &ready); - n = select(loop_master + 1, &ready, NULL, &ready, timo); - if (n < 0 && errno != EINTR) { - syslog(LOG_ERR, "select: %m"); - die(1); - } -} - - -/* - * 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) { - syslog(LOG_ERR, "select: %m"); - die(1); - } -} - - -/* - * read_packet - get a PPP packet from the serial device. - */ -int -read_packet(u_char *buf) -{ - int len; - - if ((len = read(ttyfd, buf, PPP_MTU + PPP_HDRLEN)) < 0) { - if (errno == EWOULDBLOCK || errno == EINTR) - return -1; - syslog(LOG_ERR, "read: %m"); - die(1); - } - return len; -} - - -/* - * get_loop_output - read characters from the loopback, form them - * into frames, 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; - - while ((n = read(loop_master, inbuf, sizeof(inbuf))) >= 0) { - if (loop_chars(inbuf, n)) - rv = 1; - } - - if (n == 0) { - syslog(LOG_ERR, "eof on loopback"); - die(1); - } else if (errno != EWOULDBLOCK){ - syslog(LOG_ERR, "read from loopback: %m"); - die(1); - } - - return rv; -} - - -/* - * ppp_send_config - configure the transmit characteristics of - * the ppp interface. - */ -void -ppp_send_config(int unit, int mtu, u_int32_t asyncmap, int pcomp, int accomp) -{ - u_int x; - struct ifreq ifr; - - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - ifr.ifr_mtu = mtu; - if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m"); - quit(); - } - - if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSASYNCMAP): %m"); - quit(); - } - - if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); - quit(); - } - x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT; - x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC; - if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); - quit(); - } -} - - -/* - * ppp_set_xaccm - set the extended transmit ACCM for the interface. - */ -void -ppp_set_xaccm(int unit, ext_accm accm) -{ - if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) - syslog(LOG_WARNING, "ioctl(set extended ACCM): %m"); -} - - -/* - * ppp_recv_config - configure the receive-side characteristics of - * the ppp interface. - */ -void -ppp_recv_config(int unit, int mru, u_int32_t asyncmap, int pcomp, int accomp) -{ - int x; - - if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %m"); - quit(); - } - if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSRASYNCMAP): %m"); - quit(); - } - if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); - quit(); - } - x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC; - if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); - quit(); - } -} - -/* - * ccp_test - ask kernel whether a given compression method - * is acceptable for use. Returns 1 if the method and parameters - * are OK, 0 if the method is known but the parameters are not OK - * (e.g. code size should be reduced), or -1 if the method is unknown. - */ -int -ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit) -{ - struct ppp_option_data data; - - data.ptr = opt_ptr; - data.length = opt_len; - data.transmit = for_transmit; - if (ioctl(ttyfd, 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; - - if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); - return; - } - x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN; - x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP; - if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) - syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); -} - -/* - * 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 x; - - if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCGFLAGS): %m"); - return 0; - } - return x & SC_DC_FERROR; -} - -/* - * get_idle_time - return how long the link has been idle. - */ -int -get_idle_time(int u, struct ppp_idle *ip) -{ - return ioctl(ppp_fd, PPPIOCGIDLE, ip) >= 0; -} - - -#ifdef PPP_FILTER -/* - * set_filters - transfer the pass and active filters to the kernel. - */ -int -set_filters(struct bpf_program *pass, struct bpf_program *active) -{ - int ret = 1; - - if (pass->bf_len > 0) { - if (ioctl(ppp_fd, PPPIOCSPASS, pass) < 0) { - syslog(LOG_ERR, "Couldn't set pass-filter in kernel: %m"); - ret = 0; - } - } - if (active->bf_len > 0) { - if (ioctl(ppp_fd, PPPIOCSACTIVE, active) < 0) { - syslog(LOG_ERR, "Couldn't set active-filter in kernel: %m"); - ret = 0; - } - } - return ret; -} -#endif - -/* - * sifvjcomp - config tcp header compression - */ -int -sifvjcomp(int u, int vjcomp, int cidcomp, int maxcid) -{ - u_int x; - - if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); - return 0; - } - x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP; - x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID; - if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); - return 0; - } - if (vjcomp && ioctl(ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { - syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); - return 0; - } - return 1; -} - -/* - * sifup - Config the interface up and enable IP packets to pass. - */ -int -sifup(int u) -{ - struct ifreq ifr; - - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); - return 0; - } - ifr.ifr_flags |= IFF_UP; - if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m"); - return 0; - } - if_is_up = 1; - return 1; -} - -/* - * 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_fd, PPPIOCSNPMODE, &npi) < 0) { - syslog(LOG_ERR, "ioctl(set NP %d mode to %d): %m", proto, mode); - return 0; - } - return 1; -} - -/* - * sifdown - Config the interface down and disable IP. - */ -int -sifdown(int u) -{ - struct ifreq ifr; - int rv; - struct npioctl npi; - - rv = 1; - npi.protocol = PPP_IP; - npi.mode = NPMODE_ERROR; - ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi); - /* ignore errors, because ppp_fd might have been closed by now. */ - - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); - rv = 0; - } else { - ifr.ifr_flags &= ~IFF_UP; - if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m"); - rv = 0; - } else - if_is_up = 0; - } - return rv; -} - -/* - * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, - * if it exists. - */ -#define SET_SA_FAMILY(addr, family) \ - BZERO((char *) &(addr), sizeof(addr)); \ - addr.sa_family = (family); \ - addr.sa_len = sizeof(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 ifaliasreq ifra; - struct ifreq ifr; - - strncpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); - SET_SA_FAMILY(ifra.ifra_addr, AF_INET); - ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o; - SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET); - ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h; - if (m != 0) { - SET_SA_FAMILY(ifra.ifra_mask, AF_INET); - ((struct sockaddr_in *) &ifra.ifra_mask)->sin_addr.s_addr = m; - } else - BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask)); - BZERO(&ifr, sizeof(ifr)); - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifr) < 0) { - if (errno != EADDRNOTAVAIL) - syslog(LOG_WARNING, "Couldn't remove interface address: %m"); - } - if (ioctl(sockfd, SIOCAIFADDR, (caddr_t) &ifra) < 0) { - if (errno != EEXIST) { - syslog(LOG_ERR, "Couldn't set interface address: %m"); - return 0; - } - syslog(LOG_WARNING, - "Couldn't set interface address: Address %s already exists", - ip_ntoa(o)); - } - ifaddrs[0] = o; - ifaddrs[1] = h; - return 1; -} - -/* - * 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) -{ - struct ifaliasreq ifra; - - ifaddrs[0] = 0; - strncpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); - SET_SA_FAMILY(ifra.ifra_addr, AF_INET); - ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o; - SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET); - ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h; - BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask)); - if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifra) < 0) { - if (errno != EADDRNOTAVAIL) - syslog(LOG_WARNING, "Couldn't delete interface address: %m"); - return 0; - } - return 1; -} - -/* - * sifdefaultroute - assign a default route through the address given. - */ -int -sifdefaultroute(int u, u_int32_t l, u_int32_t g) -{ - return dodefaultroute(g, 's'); -} - -/* - * cifdefaultroute - delete a default route through the address given. - */ -int -cifdefaultroute(int u, u_int32_t l, u_int32_t g) -{ - return dodefaultroute(g, 'c'); -} - -/* - * dodefaultroute - talk to a routing socket to add/delete a default route. - */ -static int -dodefaultroute(u_int32_t g, int cmd) -{ - int routes; - struct { - struct rt_msghdr hdr; - struct sockaddr_in dst; - struct sockaddr_in gway; - struct sockaddr_in mask; - } rtmsg; - - if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { - syslog(LOG_ERR, "Couldn't %s default route: socket: %m", - cmd=='s'? "add": "delete"); - return 0; - } - - memset(&rtmsg, 0, sizeof(rtmsg)); - rtmsg.hdr.rtm_type = cmd == 's'? RTM_ADD: RTM_DELETE; - rtmsg.hdr.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; - rtmsg.hdr.rtm_version = RTM_VERSION; - rtmsg.hdr.rtm_seq = ++rtm_seq; - rtmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; - rtmsg.dst.sin_len = sizeof(rtmsg.dst); - rtmsg.dst.sin_family = AF_INET; - rtmsg.gway.sin_len = sizeof(rtmsg.gway); - rtmsg.gway.sin_family = AF_INET; - rtmsg.gway.sin_addr.s_addr = g; - rtmsg.mask.sin_len = sizeof(rtmsg.dst); - rtmsg.mask.sin_family = AF_INET; - - rtmsg.hdr.rtm_msglen = sizeof(rtmsg); - if (write(routes, &rtmsg, sizeof(rtmsg)) < 0) { - syslog(LOG_ERR, "Couldn't %s default route: %m", - cmd=='s'? "add": "delete"); - close(routes); - return 0; - } - - close(routes); - default_route_gateway = (cmd == 's')? g: 0; - return 1; -} - -#if RTM_VERSION >= 3 - -/* - * sifproxyarp - Make a proxy ARP entry for the peer. - */ -static struct { - struct rt_msghdr hdr; - struct sockaddr_inarp dst; - struct sockaddr_dl hwa; - char extra[128]; -} arpmsg; - -static int arpmsg_valid; - -int -sifproxyarp(int unit, u_int32_t hisaddr) -{ - int routes; - - /* - * Get the hardware address of an interface on the same subnet - * as our local address. - */ - memset(&arpmsg, 0, sizeof(arpmsg)); - if (!get_ether_addr(hisaddr, &arpmsg.hwa)) { - syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP"); - return 0; - } - - if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { - syslog(LOG_ERR, "Couldn't add proxy arp entry: socket: %m"); - return 0; - } - - arpmsg.hdr.rtm_type = RTM_ADD; - arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC; - arpmsg.hdr.rtm_version = RTM_VERSION; - arpmsg.hdr.rtm_seq = ++rtm_seq; - arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY; - arpmsg.hdr.rtm_inits = RTV_EXPIRE; - arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp); - arpmsg.dst.sin_family = AF_INET; - arpmsg.dst.sin_addr.s_addr = hisaddr; - arpmsg.dst.sin_other = SIN_PROXY; - - arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg - + arpmsg.hwa.sdl_len; - if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) { - syslog(LOG_ERR, "Couldn't add proxy arp entry: %m"); - close(routes); - return 0; - } - - close(routes); - arpmsg_valid = 1; - proxy_arp_addr = hisaddr; - return 1; -} - -/* - * cifproxyarp - Delete the proxy ARP entry for the peer. - */ -int -cifproxyarp(int unit, u_int32_t hisaddr) -{ - int routes; - - if (!arpmsg_valid) - return 0; - arpmsg_valid = 0; - - arpmsg.hdr.rtm_type = RTM_DELETE; - arpmsg.hdr.rtm_seq = ++rtm_seq; - - if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { - syslog(LOG_ERR, "Couldn't delete proxy arp entry: socket: %m"); - return 0; - } - - if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) { - syslog(LOG_ERR, "Couldn't delete proxy arp entry: %m"); - close(routes); - return 0; - } - - close(routes); - proxy_arp_addr = 0; - return 1; -} - -#else /* RTM_VERSION */ - -/* - * sifproxyarp - Make a proxy ARP entry for the peer. - */ -int -sifproxyarp(int unit, u_int32_t hisaddr) -{ - struct arpreq arpreq; - struct { - struct sockaddr_dl sdl; - char space[128]; - } dls; - - BZERO(&arpreq, sizeof(arpreq)); - - /* - * Get the hardware address of an interface on the same subnet - * as our local address. - */ - if (!get_ether_addr(hisaddr, &dls.sdl)) { - syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP"); - return 0; - } - - arpreq.arp_ha.sa_len = sizeof(struct sockaddr); - arpreq.arp_ha.sa_family = AF_UNSPEC; - BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen); - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; - arpreq.arp_flags = ATF_PERM | ATF_PUBL; - if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) { - syslog(LOG_ERR, "Couldn't add 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; - - BZERO(&arpreq, sizeof(arpreq)); - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; - if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) { - syslog(LOG_WARNING, "Couldn't delete proxy arp entry: %m"); - return 0; - } - proxy_arp_addr = 0; - return 1; -} -#endif /* RTM_VERSION */ - -/* - * 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_dl *hwaddr) -{ - struct ifreq *ifr, *ifend, *ifp; - u_int32_t ina, mask; - struct sockaddr_dl *dla; - struct ifreq ifreq; - struct ifconf ifc; - struct ifreq ifs[MAX_IFS]; - - ifc.ifc_len = sizeof(ifs); - ifc.ifc_req = ifs; - if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { - syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m"); - return 0; - } - - /* - * Scan through looking for an interface with an Internet - * address on the same subnet as `ipaddr'. - */ - ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - for (ifr = ifc.ifc_req; ifr < ifend; - ifr = (struct ifreq *) ((char *)&ifr->ifr_addr - + MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr)))) { - if (ifr->ifr_addr.sa_family == AF_INET) { - ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - /* - * Check that the interface is up, and not point-to-point - * or loopback. - */ - if (ioctl(sockfd, 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(sockfd, SIOCGIFNETMASK, &ifreq) < 0) - continue; - mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr; - if ((ipaddr & mask) != (ina & mask)) - continue; - - break; - } - } - - if (ifr >= ifend) - return 0; - syslog(LOG_INFO, "found interface %s for proxy arp", ifr->ifr_name); - - /* - * Now scan through again looking for a link-level address - * for this interface. - */ - ifp = ifr; - for (ifr = ifc.ifc_req; ifr < ifend; ) { - if (strcmp(ifp->ifr_name, ifr->ifr_name) == 0 - && ifr->ifr_addr.sa_family == AF_LINK) { - /* - * Found the link-level address - copy it out - */ - dla = (struct sockaddr_dl *) &ifr->ifr_addr; - BCOPY(dla, hwaddr, dla->sdl_len); - return 1; - } - ifr = (struct ifreq *) ((char *)&ifr->ifr_addr - + MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr))); - } - - return 0; -} - -/* - * 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(sockfd, SIOCGIFCONF, &ifc) < 0) { - syslog(LOG_WARNING, "ioctl(SIOCGIFCONF): %m"); - return mask; - } - ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - for (ifr = ifc.ifc_req; ifr < ifend; - ifr = (struct ifreq *) ((char *)&ifr->ifr_addr - + MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr)))) { - /* - * Check the interface's internet address. - */ - if (ifr->ifr_addr.sa_family != AF_INET) - continue; - ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; - if ((ntohl(ina) & nmask) != (addr & nmask)) - continue; - /* - * Check that the interface is up, and not point-to-point or loopback. - */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - if (ioctl(sockfd, 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(sockfd, SIOCGIFNETMASK, &ifreq) < 0) - continue; - mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr; - } - - return mask; -} - -/* - * Use the hostid as part of the random number seed. - */ -int -get_host_seed(void) -{ - return gethostid(); -} - -/* - * lock - create a lock file for the named lock device - */ -#define LOCK_PREFIX "/var/spool/lock/LCK.." - -int -lock(char *dev) -{ - char hdb_lock_buffer[12]; - int fd, pid, n; - char *p; - - if ((p = strrchr(dev, '/')) != NULL) - dev = p + 1; - lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1); - if (lock_file == NULL) - novm("lock file name"); - strcat(strcpy(lock_file, LOCK_PREFIX), dev); - - 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, hdb_lock_buffer, 11); - if (n <= 0) { - syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file); - close(fd); - } else { - hdb_lock_buffer[n] = 0; - pid = atoi(hdb_lock_buffer); - if (kill(pid, 0) == -1 && errno == ESRCH) { - /* pid no longer exists - remove the lock file */ - if (unlink(lock_file) == 0) { - close(fd); - syslog(LOG_NOTICE, "Removed stale lock on %s (pid %d)", - dev, pid); - continue; - } else - syslog(LOG_WARNING, "Couldn't remove stale lock on %s", - dev); - } else - syslog(LOG_NOTICE, "Device %s is locked by pid %d", - dev, pid); - } - close(fd); - } else - syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file); - free(lock_file); - lock_file = NULL; - return -1; - } - - sprintf(hdb_lock_buffer, "%10d\n", getpid()); - write(fd, hdb_lock_buffer, 11); - - close(fd); - return 0; -} - -/* - * unlock - remove our lockfile - */ -void -unlock(void) -{ - if (lock_file) { - unlink(lock_file); - free(lock_file); - lock_file = NULL; - } -} diff --git a/usr.sbin/pppd/upap.c b/usr.sbin/pppd/upap.c deleted file mode 100644 index 32074d4d67..0000000000 --- a/usr.sbin/pppd/upap.c +++ /dev/null @@ -1,585 +0,0 @@ -/* - * upap.c - User/Password Authentication Protocol. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/upap.c,v 1.8 1999/08/28 01:19:08 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/upap.c,v 1.4 2005/11/24 23:42:54 swildner Exp $ - */ - -/* - * TODO: - */ - -#include -#include -#include -#include -#include - -#include "pppd.h" -#include "upap.h" - -/* - * 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, - 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 */ - syslog(LOG_ERR, "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) { - syslog(LOG_ERR, "PAP authentication failed due to protocol-reject"); - auth_withpeer_fail(unit, PPP_PAP); - } - if (u->us_serverstate == UPAPSS_LISTEN) { - syslog(LOG_ERR, "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((LOG_INFO, "pap_input: rcvd short header.")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < UPAP_HEADERLEN) { - UPAPDEBUG((LOG_INFO, "pap_input: rcvd illegal length.")); - return; - } - if (len > l) { - UPAPDEBUG((LOG_INFO, "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; - int retcode; - char *msg; - int msglen; - - UPAPDEBUG((LOG_INFO, "pap_rauth: Rcvd id %d.", id)); - - 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 < sizeof (u_char)) { - UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.")); - return; - } - GETCHAR(ruserlen, inp); - len -= sizeof (u_char) + ruserlen + sizeof (u_char); - if (len < 0) { - UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.")); - return; - } - ruser = (char *) inp; - INCPTR(ruserlen, inp); - GETCHAR(rpasswdlen, inp); - if (len < rpasswdlen) { - UPAPDEBUG((LOG_INFO, "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, &msglen); - BZERO(rpasswd, rpasswdlen); - - upap_sresp(u, retcode, id, msg, msglen); - - if (retcode == UPAP_AUTHACK) { - u->us_serverstate = UPAPSS_OPEN; - auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen); - } else { - u->us_serverstate = UPAPSS_BADAUTH; - 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; - - UPAPDEBUG((LOG_INFO, "pap_rauthack: Rcvd id %d.", id)); - if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */ - return; - - /* - * Parse message. - */ - if (len < sizeof (u_char)) { - UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.")); - return; - } - GETCHAR(msglen, inp); - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG((LOG_INFO, "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); -} - - -/* - * upap_rauthnak - Receive Authenticate-Nakk. - */ -static void -upap_rauthnak(upap_state *u, u_char *inp, int id, int len) -{ - u_char msglen; - char *msg; - - UPAPDEBUG((LOG_INFO, "pap_rauthnak: Rcvd id %d.", id)); - if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */ - return; - - /* - * Parse message. - */ - if (len < sizeof (u_char)) { - UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.")); - return; - } - GETCHAR(msglen, inp); - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.")); - return; - } - msg = (char *) inp; - PRINTMSG(msg, msglen); - - u->us_clientstate = UPAPCS_BADAUTH; - - syslog(LOG_ERR, "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); - - UPAPDEBUG((LOG_INFO, "pap_sauth: Sent id %d.", u->us_id)); - - 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); - - UPAPDEBUG((LOG_INFO, "pap_sresp: Sent code %d, id %d.", code, id)); -} - -/* - * 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="); - print_string(pwd, wlen, 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; -} diff --git a/usr.sbin/pppd/upap.h b/usr.sbin/pppd/upap.h deleted file mode 100644 index c304ecf072..0000000000 --- a/usr.sbin/pppd/upap.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * upap.h - User/Password Authentication Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * 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 Carnegie Mellon University. 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. - * - * $FreeBSD: src/usr.sbin/pppd/upap.h,v 1.7 1999/08/28 01:19:09 peter Exp $ - * $DragonFly: src/usr.sbin/pppd/upap.h,v 1.3 2003/11/03 19:31:40 eirikn Exp $ - */ - -/* - * Packet header = Code, id, length. - */ -#define UPAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short)) - - -/* - * 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 */ - u_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; diff --git a/usr.sbin/pppstats/Makefile b/usr.sbin/pppstats/Makefile deleted file mode 100644 index 97addde96f..0000000000 --- a/usr.sbin/pppstats/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD: src/usr.sbin/pppstats/Makefile,v 1.7.2.1 2001/04/25 12:10:35 ru Exp $ -# $DragonFly: src/usr.sbin/pppstats/Makefile,v 1.3 2004/01/31 06:56:46 dillon Exp $ - -PROG= pppstats -MAN= pppstats.8 -WARNS?= 3 - -.include diff --git a/usr.sbin/pppstats/pppstats.8 b/usr.sbin/pppstats/pppstats.8 deleted file mode 100644 index 300736ac81..0000000000 --- a/usr.sbin/pppstats/pppstats.8 +++ /dev/null @@ -1,191 +0,0 @@ -.\" $FreeBSD: src/usr.sbin/pppstats/pppstats.8,v 1.10 2000/03/03 09:11:28 sheldonh Exp $ -.Dd June 26, 1995 -.Dt PPPSTATS 8 -.Os -.Sh NAME -.Nm pppstats -.Nd print PPP statistics -.Sh SYNOPSIS -.Nm -.Op Fl arvz -.Op Fl c Ar count -.Op Fl w Ar secs -.Ar interface -.Sh DESCRIPTION -The -.Nm -utility reports PPP-related statistics at regular intervals for the -specified PPP interface. -If the interface is unspecified, it will default to -.Ar 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: -.Bl -tag -width indent -.It Fl 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. -.It Fl c Ar count -Repeat the display -.Ar count -times. -If this option is not specified, the default repeat count is 1 if the -.Fl w -option is not specified, otherwise infinity. -.It Fl r -Display additional statistics summarizing the compression ratio -achieved by the packet compression algorithm in use. -.It Fl v -Display additional statistics relating to the performance of the Van -Jacobson TCP header compression algorithm. -.It Fl w Ar secs -Pause -.Ar secs -seconds between each display. -If this option is not specified, the default interval is 5 seconds. -.It Fl z -Instead of the standard display, show statistics indicating the -performance of the packet compression algorithm in use. -.El -.Pp -The following fields are printed on the input side when the -.Fl z -option is not used: -.Bl -tag -width VJCOMP -.It IN -The total number of bytes received by this interface. -.It PACK -The total number of packets received by this interface. -.It VJCOMP -The number of header-compressed TCP packets received by this interface. -.It VJUNC -The number of header-uncompressed TCP packets received by this -interface. -Not reported when the -.Fl r -option is specified. -.It VJERR -The number of corrupted or bogus header-compressed TCP packets -received by this interface. -Not reported when the -.Fl r -option is specified. -.It VJTOSS -The number of VJ header-compressed TCP packets dropped on reception by -this interface because of preceding errors. -Only reported when the -.Fl v -option is specified. -.It NON-VJ -The total number of non-TCP packets received by this interface. -Only reported when the -.Fl v -option is specified. -.It 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 -.Fl r -option is specified. -.It UBYTE -The total number of bytes received, after decompression of compressed -packets. -Only reported when the -.Fl r -option is specified. -.El -.Pp -The following fields are printed on the output side: -.Bl -tag -width VJCOMP -.It OUT -The total number of bytes transmitted from this interface. -.It PACK -The total number of packets transmitted from this interface. -.It VJCOMP -The number of TCP packets transmitted from this interface with -VJ-compressed TCP headers. -.It VJUNC -The number of TCP packets transmitted from this interface with -VJ-uncompressed TCP headers. -Not reported when the -.Fl r -option is specified. -.It NON-VJ -The total number of non-TCP packets transmitted from this interface. -Not reported when the -.Fl r -option is specified. -.It VJSRCH -The number of searches for the cached header entry for a VJ header -compressed TCP packet. -Only reported when the -.Fl v -option is specified. -.It VJMISS -The number of failed searches for the cached header entry for a -VJ header compressed TCP packet. -Only reported when the -.Fl v -option is specified. -.It 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 -.Fl r -option is specified. -.It UBYTE -The total number of bytes to be transmitted, before packet compression -is applied. -Only reported when the -.Fl r -option is specified. -.El -.Pp -When the -.Fl z -option is specified, -.Nm -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: -.Bl -tag -width "INCOMPRESSIBLE BYTE" -.It COMPRESSED BYTE -The number of bytes of compressed packets received. -.It COMPRESSED PACK -The number of compressed packets received. -.It INCOMPRESSIBLE BYTE -The number of bytes of incompressible packets (that is, those which -were transmitted in uncompressed form) received. -.It INCOMPRESSIBLE PACK -The number of incompressible packets received. -.It 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). -.El -.Pp -The fields displayed on the output side are: -.Bl -tag -width "INCOMPRESSIBLE BYTE" -.It COMPRESSED BYTE -The number of bytes of compressed packets transmitted. -.It COMPRESSED PACK -The number of compressed packets transmitted. -.It INCOMPRESSIBLE BYTE -The number of bytes of incompressible packets transmitted (that is, -those which were transmitted in uncompressed form). -.It INCOMPRESSIBLE PACK -The number of incompressible packets transmitted. -.It COMP RATIO -The recent compression ratio for outgoing packets. -.El -.Sh SEE ALSO -.Xr pppd 8 diff --git a/usr.sbin/pppstats/pppstats.c b/usr.sbin/pppstats/pppstats.c deleted file mode 100644 index c58f3e2f3a..0000000000 --- a/usr.sbin/pppstats/pppstats.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - * 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. - * - * $FreeBSD: src/usr.sbin/pppstats/pppstats.c,v 1.13 1999/08/28 01:19:11 peter Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef STREAMS -#include /* *BSD, Linux, NeXT, Ultrix etc. */ -#include -#include - -#else /* STREAMS */ -#include /* SVR4, Solaris 2, SunOS 4, OSF/1, etc. */ -#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 unit; -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 - -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); - -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 ifpppstatsreq req; - - memset (&req, 0, sizeof (req)); - -#ifdef _linux_ - req.stats_ptr = (caddr_t) &req.stats; -#undef ifr_name -#define ifr_name ifr__name -#endif - - strncpy(req.ifr_name, interface, sizeof(req.ifr_name)); - 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); - } - *curp = req.stats; -} - -static void -get_ppp_cstats(struct ppp_comp_stats *csp) -{ - struct ifpppcstatsreq creq; - - memset (&creq, 0, sizeof (creq)); - -#ifdef _linux_ - creq.stats_ptr = (caddr_t) &creq.stats; -#undef ifr_name -#define ifr_name ifr__name -#endif - - strncpy(creq.ifr_name, interface, sizeof(creq.ifr_name)); - if (ioctl(s, SIOCGPPPCSTATS, &creq) < 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 (creq.stats.c.bytes_out == 0) - creq.stats.c.ratio = 0.0; - else - creq.stats.c.ratio = (double) creq.stats.c.in_count / - (double) creq.stats.c.bytes_out; - - if (creq.stats.d.bytes_out == 0) - creq.stats.d.ratio = 0.0; - else - creq.stats.d.ratio = (double) creq.stats.d.in_count / - (double) creq.stats.d.bytes_out; -#endif - - *csp = creq.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, 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(ppp_comp_stats *csp) -{ - if (strioctl(s, PPPIO_GETCSTAT, 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) -{ - 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); - - signal(SIGALRM, catchalarm); - signalled = 0; - 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; - alarm(interval); - - if (!aflag) { - old = cur; - ocs = ccs; - ratef = dflag; - } - } -} - -int -main(int argc, char *argv[]) -{ - int c; -#ifdef STREAMS - char *dev; -#endif - - interface = "ppp0"; - 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]; - - if (sscanf(interface, "ppp%d", &unit) != 1) { - fprintf(stderr, "%s: invalid interface '%s' specified\n", - progname, interface); - } - -#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, sizeof(ifr.ifr_name)); - if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { - fprintf(stderr, "%s: nonexistent interface '%s' specified\n", - progname, interface); - exit(1); - } - } - -#else /* STREAMS */ -#ifdef __osf__ - dev = "/dev/streams/ppp"; -#else - dev = "/dev/ppp"; -#endif - if ((s = open(dev, O_RDONLY)) < 0) { - fprintf(stderr, "%s: couldn't open ", progname); - perror(dev); - exit(1); - } - if (strioctl(s, PPPIO_ATTACH, &unit, sizeof(int), 0) < 0) { - fprintf(stderr, "%s: ppp%d is not available\n", progname, unit); - exit(1); - } - -#endif /* STREAMS */ - - intpr(); - exit(0); -} diff --git a/usr.sbin/slstat/slstat.8 b/usr.sbin/slstat/slstat.8 index c2060b6c7d..0be37e5202 100644 --- a/usr.sbin/slstat/slstat.8 +++ b/usr.sbin/slstat/slstat.8 @@ -27,9 +27,8 @@ .\" .\" From: @(#)slstat.8 6.8 (Berkeley) 6/20/91 .\" $FreeBSD: src/usr.sbin/slstat/slstat.8,v 1.14.2.2 2001/08/16 15:56:33 ru Exp $ -.\" $DragonFly: src/usr.sbin/slstat/slstat.8,v 1.4 2008/05/02 02:05:08 swildner Exp $ .\" -.Dd October 11, 1996 +.Dd October 17, 2017 .Dt SLSTAT 8 .Os .Sh NAME @@ -118,7 +117,6 @@ seconds. .Xr ps 1 , .Xr systat 1 , .Xr iostat 8 , -.Xr pppstats 8 , .Xr pstat 8 .Pp The sections starting with ``Interpreting system activity'' in