From 6aae3517ed2500fb963ba0a4264b4756088dd0f4 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Wed, 20 Oct 2021 21:08:13 -0700 Subject: [PATCH] Retire synchronous PPP kernel driver sppp(4). The last two drivers that required sppp are cp(4) and ce(4). These devices are still produced and can be purchased at Cronyx . Since Roman Kurakin has quit them, they no longer support FreeBSD officially. Later they have dropped support for Linux drivers to. As of mid-2020 they don't even have a developer to maintain their Windows driver. However, their support verbally told me that they could provide aid to a FreeBSD developer with documentaion in case if there appears a new customer for their devices. These drivers have a feature to not use sppp(4) and create an interface, but instead expose the device as netgraph(4) node. Then, you can attach ng_ppp(4) with help of ports/net/mpd5 on top of the node and get your synchronous PPP. Alternatively you can attach ng_frame_relay(4) or ng_cisco(4) for HDLC. Actually, last time I used cp(4) back in 2004, using netgraph(4) instead of sppp(4) was already the right way to do. Thus, remove the sppp(4) related part of the drivers and enable by default the negraph(4) part. Further maintenance of these drivers in the tree shouldn't be a big deal. While doing that, remove some cruft and enable cp(4) compilation on amd64. The ce(4) for some unknown reason marks its internal DDK functions with __attribute__ fastcall, which most likely is safe to remove, but without hardware I'm not going to do that, so ce(4) remains i386-only. Reviewed by: emaste, imp, donner Differential Revision: https://reviews.freebsd.org/D32590 See also: https://reviews.freebsd.org/D23928 --- ObsoleteFiles.inc | 11 + UPDATING | 5 + lib/libc/net/getnameinfo.c | 2 +- lib/libnetgraph/debug.c | 2 - libexec/rc/netstart | 1 - libexec/rc/rc.conf | 6 - libexec/rc/rc.d/Makefile | 1 - libexec/rc/rc.d/netif | 2 +- libexec/rc/rc.d/sppp | 37 - rescue/rescue/Makefile | 2 +- sbin/Makefile | 1 - sbin/sconfig/sconfig.8 | 5 - sbin/spppcontrol/Makefile | 9 - sbin/spppcontrol/Makefile.depend | 17 - sbin/spppcontrol/spppcontrol.8 | 275 -- sbin/spppcontrol/spppcontrol.c | 266 -- share/man/man4/Makefile | 2 - share/man/man4/man4.i386/ce.4 | 44 +- share/man/man4/man4.i386/cp.4 | 44 +- share/man/man4/netgraph.4 | 1 - share/man/man4/ng_sppp.4 | 172 - share/man/man4/sppp.4 | 238 - share/man/man5/rc.conf.5 | 15 - sys/conf/NOTES | 5 - sys/conf/files | 6 +- sys/conf/files.i386 | 3 - sys/conf/files.x86 | 3 + sys/conf/options.i386 | 3 - sys/dev/ce/if_ce.c | 328 +- sys/dev/ce/ng_ce.h | 4 - sys/{i386/include => dev/cp}/cserial.h | 0 sys/dev/cp/if_cp.c | 316 +- sys/dev/cp/ng_cp.h | 4 - sys/i386/conf/NOTES | 9 +- sys/modules/Makefile | 2 - sys/modules/ce/Makefile | 21 +- sys/modules/cp/Makefile | 21 +- sys/modules/netgraph/Makefile | 1 - sys/modules/netgraph/sppp/Makefile | 7 - sys/modules/sppp/Makefile | 18 - sys/net/if_sppp.h | 234 - sys/net/if_spppfr.c | 611 --- sys/net/if_spppsubr.c | 5418 ----------------------- sys/netgraph/ng_sppp.c | 411 -- sys/netgraph/ng_sppp.h | 39 - sys/x86/conf/NOTES | 5 + targets/pseudo/userland/Makefile.depend | 1 - 47 files changed, 71 insertions(+), 8557 deletions(-) delete mode 100755 libexec/rc/rc.d/sppp delete mode 100644 sbin/spppcontrol/Makefile delete mode 100644 sbin/spppcontrol/Makefile.depend delete mode 100644 sbin/spppcontrol/spppcontrol.8 delete mode 100644 sbin/spppcontrol/spppcontrol.c delete mode 100644 share/man/man4/ng_sppp.4 delete mode 100644 share/man/man4/sppp.4 rename sys/{i386/include => dev/cp}/cserial.h (100%) delete mode 100644 sys/modules/netgraph/sppp/Makefile delete mode 100644 sys/modules/sppp/Makefile delete mode 100644 sys/net/if_sppp.h delete mode 100644 sys/net/if_spppfr.c delete mode 100644 sys/net/if_spppsubr.c delete mode 100644 sys/netgraph/ng_sppp.c delete mode 100644 sys/netgraph/ng_sppp.h diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 7c5e534d21d4..b6a2d299bc8c 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -40,6 +40,17 @@ # xargs -n1 | sort | uniq -d; # done +# 20211022 +OLD_FILES+=sbin/spppcontrol +.if ${TARGET_ARCH} == "i386" +OLD_FILES+=usr/include/machine/cserial.h +.endif +OLD_FILES+=usr/include/net/if_sppp.h +OLD_FILES+=usr/include/netgraph/ng_sppp.h +OLD_FILES+=usr/share/man/man4/ng_sppp.4.gz +OLD_FILES+=usr/share/man/man4/sppp.4.gz +OLD_FILES+=usr/share/man/man8/spppcontrol.8.gz + # 20210929: OLD_FILES+=usr/sbin/hcseriald OLD_FILES+=usr/share/man/man8/hcseriald.8.gz diff --git a/UPDATING b/UPDATING index 8028c5f192cb..765722b62617 100644 --- a/UPDATING +++ b/UPDATING @@ -27,6 +27,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 14.x IS SLOW: world, or to merely disable the most expensive debugging functionality at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20211022: + The synchronous PPP kernel driver sppp(4) has been removed. + The cp(4) and ce(4) drivers are now always compiled with netgraph(4) + support, formerly enabled by NETGRAPH_CRONYX option. + 20211020: sh(1) is now the default shell for the root user. To force root to use the csh shell, please run the following command as root: diff --git a/lib/libc/net/getnameinfo.c b/lib/libc/net/getnameinfo.c index ad54920aa793..b72734e56ed3 100644 --- a/lib/libc/net/getnameinfo.c +++ b/lib/libc/net/getnameinfo.c @@ -467,7 +467,7 @@ getnameinfo_link(const struct afd *afd, * The following have zero-length addresses. * IFT_GIF (net/if_gif.c) * IFT_LOOP (net/if_loop.c) - * IFT_PPP (net/if_ppp.c, net/if_spppsubr.c) + * IFT_PPP (net/if_tuntap.c) * IFT_SLIP (net/if_sl.c, net/if_strip.c) * IFT_STF (net/if_stf.c) * IFT_L2VLAN (net/if_vlan.c) diff --git a/lib/libnetgraph/debug.c b/lib/libnetgraph/debug.c index f44504140b8b..513d3350760d 100644 --- a/lib/libnetgraph/debug.c +++ b/lib/libnetgraph/debug.c @@ -96,7 +96,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -172,7 +171,6 @@ static const struct ng_cookie cookies[] = { COOKIE(SOCKET), COOKIE(SOURCE), COOKIE(SPLIT), - COOKIE(SPPP), COOKIE(TAG), COOKIE(TCPMSS), COOKIE(TEE), diff --git a/libexec/rc/netstart b/libexec/rc/netstart index fa4ce382e4ff..d40ee05edd4d 100755 --- a/libexec/rc/netstart +++ b/libexec/rc/netstart @@ -43,7 +43,6 @@ _start=quietstart /etc/rc.d/ipfilter ${_start} /etc/rc.d/ipnat ${_start} /etc/rc.d/ipfs ${_start} -/etc/rc.d/sppp ${_start} /etc/rc.d/netif ${_start} /etc/rc.d/ipsec ${_start} /etc/rc.d/ppp ${_start} diff --git a/libexec/rc/rc.conf b/libexec/rc/rc.conf index 6f4a3a1eb3f3..0cfee2d9c194 100644 --- a/libexec/rc/rc.conf +++ b/libexec/rc/rc.conf @@ -262,12 +262,6 @@ cloned_interfaces="" # List of cloned network interfaces to create. # #autobridge_interfaces="bridge0" # List of bridges to check #autobridge_bridge0="tap* vlan0" # Interface glob to automatically add to the bridge -# -# If you have any sppp(4) interfaces above, you might also want to set -# the following parameters. Refer to spppcontrol(8) for their meaning. -sppp_interfaces="" # List of sppp interfaces. -#sppp_interfaces="...0" # example: sppp over ... -#spppconfig_...0="authproto=chap myauthname=foo myauthsecret='top secret' hisauthname=some-gw hisauthsecret='another secret'" # User ppp configuration. ppp_enable="NO" # Start user-ppp (or NO). diff --git a/libexec/rc/rc.d/Makefile b/libexec/rc/rc.d/Makefile index 5981b3b03d17..4c7267552526 100644 --- a/libexec/rc/rc.d/Makefile +++ b/libexec/rc/rc.d/Makefile @@ -96,7 +96,6 @@ CONFS= DAEMON \ savecore \ securelevel \ serial \ - sppp \ statd \ static_arp \ static_ndp \ diff --git a/libexec/rc/rc.d/netif b/libexec/rc/rc.d/netif index 3dbb3e1a9588..ae30299bfc52 100755 --- a/libexec/rc/rc.d/netif +++ b/libexec/rc/rc.d/netif @@ -26,7 +26,7 @@ # # PROVIDE: netif -# REQUIRE: FILESYSTEMS iovctl serial sppp sysctl +# REQUIRE: FILESYSTEMS iovctl serial sysctl # REQUIRE: hostid # KEYWORD: nojailvnet diff --git a/libexec/rc/rc.d/sppp b/libexec/rc/rc.d/sppp deleted file mode 100755 index b6b02876d4fe..000000000000 --- a/libexec/rc/rc.d/sppp +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -# -# $FreeBSD$ -# - -# PROVIDE: sppp -# REQUIRE: root -# BEFORE: netif -# KEYWORD: nojail - -. /etc/rc.subr - -name="sppp" -desc="Point to point protocol network layer for synchronous lines" -start_cmd="sppp_start" -stop_cmd=":" - -sppp_start() -{ - # Special options for sppp(4) interfaces go here. These need - # to go _before_ the general ifconfig since in the case - # of hardwired (no link1 flag) but required authentication, you - # cannot pass auth parameters down to the already running interface. - # - for ifn in ${sppp_interfaces}; do - eval spppcontrol_args=\$spppconfig_${ifn} - if [ -n "${spppcontrol_args}" ]; then - # The auth secrets might contain spaces; in order - # to retain the quotation, we need to eval them - # here. - eval spppcontrol ${ifn} ${spppcontrol_args} - fi - done -} - -load_rc_config $name -run_rc_command "$1" diff --git a/rescue/rescue/Makefile b/rescue/rescue/Makefile index 42094340e768..90aaea3cb709 100644 --- a/rescue/rescue/Makefile +++ b/rescue/rescue/Makefile @@ -101,7 +101,7 @@ CRUNCH_PROGS_sbin= \ mount_udf mount_unionfs newfs \ newfs_msdos nos-tun ping reboot \ restore rcorder route savecore \ - shutdown spppcontrol swapon sysctl tunefs umount + shutdown swapon sysctl tunefs umount .if ${MK_CCD} != "no" CRUNCH_PROGS_sbin+= ccdconfig diff --git a/sbin/Makefile b/sbin/Makefile index 6d6b647651ad..ade73fc8b0ee 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -63,7 +63,6 @@ SUBDIR=adjkerntz \ savecore \ setkey \ shutdown \ - spppcontrol \ swapon \ sysctl \ tunefs \ diff --git a/sbin/sconfig/sconfig.8 b/sbin/sconfig/sconfig.8 index 713f76d88c9d..a55bf911e3dd 100644 --- a/sbin/sconfig/sconfig.8 +++ b/sbin/sconfig/sconfig.8 @@ -216,9 +216,6 @@ Select the Frame Relay synchronous protocol T1.617 Annex D). .It Cm ppp Select the synchronous PPP protocol. -PPP parameters can be configured using the -.Xr spppcontrol 8 -utility. .It Sm Cm keepalive No = Bro Cm on , off Brc Sm Turn on/off transmission of keepalive messages. This option is used only for synchronous PPP. @@ -569,10 +566,8 @@ Test error (G.703 only). .Sh SEE ALSO .Xr stty 1 , .Xr ioctl 2 , -.Xr sppp 4 , .Xr ifconfig 8 , .Xr route 8 , -.Xr spppcontrol 8 .\"-------------------------------------------------------------- .Sh HISTORY The diff --git a/sbin/spppcontrol/Makefile b/sbin/spppcontrol/Makefile deleted file mode 100644 index 04173201cfde..000000000000 --- a/sbin/spppcontrol/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $FreeBSD$ - -PACKAGE= ppp - -PROG= spppcontrol -MAN= spppcontrol.8 -WARNS?= 2 - -.include diff --git a/sbin/spppcontrol/Makefile.depend b/sbin/spppcontrol/Makefile.depend deleted file mode 100644 index 6cfaab1c3644..000000000000 --- a/sbin/spppcontrol/Makefile.depend +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/sbin/spppcontrol/spppcontrol.8 b/sbin/spppcontrol/spppcontrol.8 deleted file mode 100644 index 4d948a60651a..000000000000 --- a/sbin/spppcontrol/spppcontrol.8 +++ /dev/null @@ -1,275 +0,0 @@ -.\" Copyright (C) 1997, 2001 by Joerg Wunsch, Dresden -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS -.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) 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. -.\" -.\" $FreeBSD$ -.\" -.Dd December 30, 2001 -.Dt SPPPCONTROL 8 -.Os -.Sh NAME -.Nm spppcontrol -.Nd display or set parameters for an sppp interface -.Sh SYNOPSIS -.Nm -.Op Fl v -.Ar ifname -.Op Ar parameter Ns Op Li = Ns Ar value -.Op Ar ... -.Sh DESCRIPTION -The -.Xr sppp 4 -driver might require a number of additional arguments or optional -parameters besides the settings that can be adjusted with -.Xr ifconfig 8 . -These are things like authentication protocol parameters, but also -other tunable configuration variables. -The -.Nm -utility can be used to display the current settings, or adjust these -parameters as required. -.Pp -For whatever intent -.Nm -is being called, at least the parameter -.Ar ifname -needs to be specified, naming the interface for which the settings -are to be performed or displayed. -Use -.Xr ifconfig 8 , -or -.Xr netstat 1 -to see which interfaces are available. -.Pp -If no other parameter is given, -.Nm -will just list the current settings for -.Ar ifname -and exit. -The reported settings include the current PPP phase the -interface is in, which can be one of the names -.Em dead , -.Em establish , -.Em authenticate , -.Em network , -or -.Em terminate . -If an authentication protocol is configured for the interface, the -name of the protocol to be used, as well as the system name to be used -or expected will be displayed, plus any possible options to the -authentication protocol if applicable. -Note that the authentication -secrets (sometimes also called -.Em keys ) -are not being returned by the underlying system call, and are thus not -displayed. -.Pp -If any additional parameter is supplied, superuser privileges are -required, and the command works in the -.Dq set -mode. -This is normally done quietly, unless the option -.Fl v -is also enabled, which will cause a final printout of the settings as -described above once all other actions have been taken. -Use of this -mode will be rejected if the interface is currently in any other phase -than -.Em dead . -Note that you can force an interface into -.Em dead -phase by calling -.Xr ifconfig 8 -with the parameter -.Cm down . -.Pp -The currently supported parameters include: -.Bl -tag -offset indent -width indent -.It Va authproto Ns Li = Ns Ar protoname -Set both, his and my authentication protocol to -.Ar protoname . -The protocol name can be one of -.Dq Li chap , -.Dq Li pap , -or -.Dq Li none . -In the latter case, the use of an authentication protocol will be -turned off for the named interface. -This has the side-effect of -clearing the other authentication-related parameters for this -interface as well (i.e., system name and authentication secret will -be forgotten). -.It Va myauthproto Ns Li = Ns Ar protoname -Same as above, but only for my end of the link. -I.e., this is the -protocol when remote is authenticator, and I am the peer required to -authenticate. -.It Va hisauthproto Ns Li = Ns Ar protoname -Same as above, but only for his end of the link. -.It Va myauthname Ns Li = Ns Ar name -Set my system name for the authentication protocol. -.It Va hisauthname Ns Li = Ns Ar name -Set his system name for the authentication protocol. -For CHAP, this -will only be used as a hint, causing a warning message if remote did -supply a different name. -For PAP, it is the name remote must use to -authenticate himself (in connection with his secret). -.It Va myauthsecret Ns Li = Ns Ar secret -Set my secret (key, password) for use in the authentication phase. -For CHAP, this will be used to compute the response hash value, based -on remote's challenge. -For PAP, it will be transmitted as plain text -together with the system name. -Do not forget to quote the secrets from -the shell if they contain shell metacharacters (or white space). -.It Va myauthkey Ns Li = Ns Ar secret -Same as above. -.It Va hisauthsecret Ns Li = Ns Ar secret -Same as above, to be used if we are an authenticator and the remote peer -needs to authenticate. -.It Va hisauthkey Ns Li = Ns Va secret -Same as above. -.It Va callin -Require remote to authenticate himself only when he is calling in, but -not when we are caller. -This is required for some peers that do not -implement the authentication protocols symmetrically (like Ascend -routers, for example). -.It Va always -The opposite of -.Va callin . -Require remote to always authenticate, regardless of which side is -placing the call. -This is the default, and will not be explicitly -displayed in the -.Dq list -mode. -.It Va norechallenge -Only meaningful with CHAP. -Do not re-challenge peer once the initial -CHAP handshake was successful. -Used to work around broken peer -implementations that cannot grok being re-challenged once the -connection is up. -.It Ar rechallenge -With CHAP, send re-challenges at random intervals while the connection -is in network phase. -(The intervals are currently in the range of 300 -through approximately 800 seconds.) -This is the default, and will not -be explicitly displayed in the -.Dq list -mode. -.It Va lcp-timeout Ns Li = Ns Ar timeout-value -Allows to change the value of the LCP restart timer. -Values are -specified in milliseconds. -The value must be between 10 and 20000 ms, -defaulting to 3000 ms. -.It Va enable-vj -Enable negotiation of Van Jacobsen header compression. -(Enabled by default.) -.It Va disable-vj -Disable negotiation of Van Jacobsen header compression. -.It Va enable-ipv6 -Enable negotiation of the IPv6 network control protocol. -(Enabled by default if the kernel has IPv6 enabled.) -.It Va disable-ipv6 -Disable negotiation of the IPv6 network control protocol. -Since every -IPv4 interface in an IPv6-enabled kernel automatically gets an IPv6 -address assigned, this option provides for a way to administratively -prevent the link from attempting to negotiate IPv6. -Note that -initialization of an IPv6 interface causes a multicast packet to be -sent, which can cause unwanted traffic costs (for dial-on-demand -interfaces). -.El -.Sh EXAMPLES -.Bd -literal -# spppcontrol bppp0 -bppp0: phase=dead - myauthproto=chap myauthname="uriah" - hisauthproto=chap hisauthname="ifb-gw" norechallenge - lcp-timeout=3000 - enable-vj - enable-ipv6 -.Ed -.Pp -Display the settings for -.Li bppp0 . -The interface is currently in -.Em dead -phase, i.e., the LCP layer is down, and no traffic is possible. -Both -ends of the connection use the CHAP protocol, my end tells remote the -system name -.Dq Li uriah , -and remote is expected to authenticate by the name -.Dq Li ifb-gw . -Once the initial CHAP handshake was successful, no further CHAP -challenges will be transmitted. -There are supposedly some known CHAP -secrets for both ends of the link which are not being shown. -.Bd -literal -# spppcontrol bppp0 \e - authproto=chap \e - myauthname=uriah myauthsecret='some secret' \e - hisauthname=ifb-gw hisauthsecret='another' \e - norechallenge -.Ed -.Pp -A possible call to -.Nm -that could have been used to bring the interface into the state shown -by the previous example. -.Sh SEE ALSO -.Xr netstat 1 , -.Xr sppp 4 , -.Xr ifconfig 8 -.Rs -.%A B. Lloyd -.%A W. Simpson -.%T "PPP Authentication Protocols" -.%O RFC 1334 -.Re -.Rs -.%A W. Simpson, Editor -.%T "The Point-to-Point Protocol (PPP)" -.%O RFC 1661 -.Re -.Rs -.%A W. Simpson -.%T "PPP Challenge Handshake Authentication Protocol (CHAP)" -.%O RFC 1994 -.Re -.Sh HISTORY -The -.Nm -utility appeared in -.Fx 3.0 . -.Sh AUTHORS -The program was written by -.An J\(:org Wunsch , -Dresden. diff --git a/sbin/spppcontrol/spppcontrol.c b/sbin/spppcontrol/spppcontrol.c deleted file mode 100644 index e56310c635e9..000000000000 --- a/sbin/spppcontrol/spppcontrol.c +++ /dev/null @@ -1,266 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1997, 2001 Joerg Wunsch - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -static void usage(void); -void print_vals(const char *ifname, struct spppreq *sp); -const char *phase_name(enum ppp_phase phase); -const char *proto_name(u_short proto); -const char *authflags(u_short flags); - -#define PPP_PAP 0xc023 -#define PPP_CHAP 0xc223 - -int -main(int argc, char **argv) -{ - int s, c; - int errs = 0, verbose = 0; - size_t off; - long to; - char *endp; - const char *ifname, *cp; - struct ifreq ifr; - struct spppreq spr; - - while ((c = getopt(argc, argv, "v")) != -1) - switch (c) { - case 'v': - verbose++; - break; - - default: - errs++; - break; - } - argv += optind; - argc -= optind; - - if (errs || argc < 1) - usage(); - - ifname = argv[0]; - strncpy(ifr.ifr_name, ifname, sizeof ifr.ifr_name); - - /* use a random AF to create the socket */ - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - err(EX_UNAVAILABLE, "ifconfig: socket"); - - argc--; - argv++; - - spr.cmd = (uintptr_t) SPPPIOGDEFS; - ifr.ifr_data = (caddr_t)&spr; - - if (ioctl(s, SIOCGIFGENERIC, &ifr) == -1) - err(EX_OSERR, "SIOCGIFGENERIC(SPPPIOGDEFS)"); - - if (argc == 0) { - /* list only mode */ - print_vals(ifname, &spr); - return 0; - } - -#define startswith(s) strncmp(argv[0], s, (off = strlen(s))) == 0 - - while (argc > 0) { - if (startswith("authproto=")) { - cp = argv[0] + off; - if (strcmp(cp, "pap") == 0) - spr.defs.myauth.proto = - spr.defs.hisauth.proto = PPP_PAP; - else if (strcmp(cp, "chap") == 0) - spr.defs.myauth.proto = - spr.defs.hisauth.proto = PPP_CHAP; - else if (strcmp(cp, "none") == 0) - spr.defs.myauth.proto = - spr.defs.hisauth.proto = 0; - else - errx(EX_DATAERR, "bad auth proto: %s", cp); - } else if (startswith("myauthproto=")) { - cp = argv[0] + off; - if (strcmp(cp, "pap") == 0) - spr.defs.myauth.proto = PPP_PAP; - else if (strcmp(cp, "chap") == 0) - spr.defs.myauth.proto = PPP_CHAP; - else if (strcmp(cp, "none") == 0) - spr.defs.myauth.proto = 0; - else - errx(EX_DATAERR, "bad auth proto: %s", cp); - } else if (startswith("myauthname=")) - strncpy(spr.defs.myauth.name, argv[0] + off, - AUTHNAMELEN); - else if (startswith("myauthsecret=") || - startswith("myauthkey=")) - strncpy(spr.defs.myauth.secret, argv[0] + off, - AUTHKEYLEN); - else if (startswith("hisauthproto=")) { - cp = argv[0] + off; - if (strcmp(cp, "pap") == 0) - spr.defs.hisauth.proto = PPP_PAP; - else if (strcmp(cp, "chap") == 0) - spr.defs.hisauth.proto = PPP_CHAP; - else if (strcmp(cp, "none") == 0) - spr.defs.hisauth.proto = 0; - else - errx(EX_DATAERR, "bad auth proto: %s", cp); - } else if (startswith("hisauthname=")) - strncpy(spr.defs.hisauth.name, argv[0] + off, - AUTHNAMELEN); - else if (startswith("hisauthsecret=") || - startswith("hisauthkey=")) - strncpy(spr.defs.hisauth.secret, argv[0] + off, - AUTHKEYLEN); - else if (strcmp(argv[0], "callin") == 0) - spr.defs.hisauth.flags |= AUTHFLAG_NOCALLOUT; - else if (strcmp(argv[0], "always") == 0) - spr.defs.hisauth.flags &= ~AUTHFLAG_NOCALLOUT; - else if (strcmp(argv[0], "norechallenge") == 0) - spr.defs.hisauth.flags |= AUTHFLAG_NORECHALLENGE; - else if (strcmp(argv[0], "rechallenge") == 0) - spr.defs.hisauth.flags &= ~AUTHFLAG_NORECHALLENGE; - else if (startswith("lcp-timeout=")) { - cp = argv[0] + off; - to = strtol(cp, &endp, 10); - if (*cp == '\0' || *endp != '\0' || - /* - * NB: 10 ms is the minimal possible value for - * hz=100. We assume no kernel has less clock - * frequency than that... - */ - to < 10 || to > 20000) - errx(EX_DATAERR, "bad lcp timeout value: %s", - cp); - spr.defs.lcp.timeout = to; - } else if (strcmp(argv[0], "enable-vj") == 0) - spr.defs.enable_vj = 1; - else if (strcmp(argv[0], "disable-vj") == 0) - spr.defs.enable_vj = 0; - else if (strcmp(argv[0], "enable-ipv6") == 0) - spr.defs.enable_ipv6 = 1; - else if (strcmp(argv[0], "disable-ipv6") == 0) - spr.defs.enable_ipv6 = 0; - else - errx(EX_DATAERR, "bad parameter: \"%s\"", argv[0]); - - argv++; - argc--; - } - - spr.cmd = (uintptr_t)SPPPIOSDEFS; - - if (ioctl(s, SIOCSIFGENERIC, &ifr) == -1) - err(EX_OSERR, "SIOCSIFGENERIC(SPPPIOSDEFS)"); - - if (verbose) - print_vals(ifname, &spr); - - return 0; -} - -static void -usage(void) -{ - fprintf(stderr, "%s\n%s\n", - "usage: spppcontrol [-v] ifname [{my|his}auth{proto|name|secret}=...]", - " spppcontrol [-v] ifname callin|always"); - exit(EX_USAGE); -} - -void -print_vals(const char *ifname, struct spppreq *sp) -{ - printf("%s:\tphase=%s\n", ifname, phase_name(sp->defs.pp_phase)); - if (sp->defs.myauth.proto) { - printf("\tmyauthproto=%s myauthname=\"%.*s\"\n", - proto_name(sp->defs.myauth.proto), - AUTHNAMELEN, sp->defs.myauth.name); - } - if (sp->defs.hisauth.proto) { - printf("\thisauthproto=%s hisauthname=\"%.*s\"%s\n", - proto_name(sp->defs.hisauth.proto), - AUTHNAMELEN, sp->defs.hisauth.name, - authflags(sp->defs.hisauth.flags)); - } - printf("\tlcp-timeout=%d ms\n", sp->defs.lcp.timeout); - printf("\t%sable-vj\n", sp->defs.enable_vj? "en": "dis"); - printf("\t%sable-ipv6\n", sp->defs.enable_ipv6? "en": "dis"); -} - -const char * -phase_name(enum ppp_phase phase) -{ - switch (phase) { - case PHASE_DEAD: return "dead"; - case PHASE_ESTABLISH: return "establish"; - case PHASE_TERMINATE: return "terminate"; - case PHASE_AUTHENTICATE: return "authenticate"; - case PHASE_NETWORK: return "network"; - } - return "illegal"; -} - -const char * -proto_name(u_short proto) -{ - static char buf[12]; - switch (proto) { - case PPP_PAP: return "pap"; - case PPP_CHAP: return "chap"; - } - sprintf(buf, "0x%x", (unsigned)proto); - return buf; -} - -const char * -authflags(u_short flags) -{ - static char buf[30]; - buf[0] = '\0'; - if (flags & AUTHFLAG_NOCALLOUT) - strcat(buf, " callin"); - if (flags & AUTHFLAG_NORECHALLENGE) - strcat(buf, " norechallenge"); - return buf; -} diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index af3ad94c9e2e..e2f68f619f37 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -379,7 +379,6 @@ MAN= aac.4 \ ng_socket.4 \ ng_source.4 \ ng_split.4 \ - ng_sppp.4 \ ng_sscfu.4 \ ng_sscop.4 \ ng_tag.4 \ @@ -529,7 +528,6 @@ MAN= aac.4 \ spigen.4 \ ${_spkr.4} \ splash.4 \ - sppp.4 \ ste.4 \ stf.4 \ stge.4 \ diff --git a/share/man/man4/man4.i386/ce.4 b/share/man/man4/man4.i386/ce.4 index 531904fd539c..451f9fb22da0 100644 --- a/share/man/man4/man4.i386/ce.4 +++ b/share/man/man4/man4.i386/ce.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 30, 2006 +.Dd October 22, 2021 .Dt CE 4 i386 .Os .Sh NAME @@ -44,29 +44,19 @@ module at boot time, place the following line in .Bd -literal -offset indent if_ce_load="YES" .Ed -.Pp -Additional options: -.Cd "device sppp" -.Cd "options NETGRAPH" -.Cd "options NETGRAPH_CRONYX" .Sh DESCRIPTION The .Nm -driver needs either -.Xr sppp 4 -or -.Xr netgraph 4 . -Which one to use is determined by the -.Dv NETGRAPH_CRONYX -option. -If this option is present in your kernel configuration file, the -.Nm -driver will be compiled with +driver creates a .Xr netgraph 4 -support. -Otherwise, it will be compiled with -.Xr sppp 4 -support. +node for each device found. +The node is usually paired with +.Xr ng_async 4 , +.Xr ng_cisco 4 , +.Xr ng_frame_relay 4 +or with +.Xr ng_ppp 4 +under control of net/mpd5 port. .Pp Refer to .Xr sconfig 8 @@ -89,12 +79,8 @@ with 32 HDLC channels. .El .Sh SEE ALSO .Xr cp 4 , -.Xr ctau 4 , -.Xr cx 4 , -.Xr sppp 4 , -.Xr ifconfig 8 , -.Xr sconfig 8 , -.Xr spppcontrol 8 +.Xr netgraph 4 , +.Xr sconfig 8 .Sh HISTORY The .Nm @@ -103,9 +89,3 @@ driver was added in .Fx 5.5 and .Fx 4.11 . -The -.Nm -driver for previous versions of -.Fx -is available from -.Pa http://www.cronyx.ru/ . diff --git a/share/man/man4/man4.i386/cp.4 b/share/man/man4/man4.i386/cp.4 index 049bb0829749..2e86e03a7de3 100644 --- a/share/man/man4/man4.i386/cp.4 +++ b/share/man/man4/man4.i386/cp.4 @@ -13,7 +13,7 @@ .\" Cronyx Id: cp.4,v 1.1.2.5 2004/06/21 17:47:40 rik Exp $ .\" $FreeBSD$ .\" -.Dd July 16, 2005 +.Dd October 22, 2021 .Dt CP 4 i386 .Os .Sh NAME @@ -34,28 +34,19 @@ module at boot time, place the following line in if_cp_load="YES" .Ed .Pp -Additional options: -.Cd "device sppp" -.Cd "options NETGRAPH" -.Cd "options NETGRAPH_CRONYX" .Sh DESCRIPTION The .Nm -driver needs either -.Xr sppp 4 -or -.Xr netgraph 4 . -Which one to use is determined by the -.Dv NETGRAPH_CRONYX -option. -If this option is present in your kernel configuration file, the -.Nm -driver will be compiled with +driver creates a .Xr netgraph 4 -support. -Otherwise, it will be compiled with -.Xr sppp 4 -support. +node for each device found. +The node is usually paired with +.Xr ng_async 4 , +.Xr ng_cisco 4 , +.Xr ng_frame_relay 4 +or with +.Xr ng_ppp 4 +under control of net/mpd5 port. .Pp Refer to .Xr sconfig 8 @@ -92,12 +83,9 @@ T3 interface STS-1 interface .El .Sh SEE ALSO -.Xr ctau 4 , -.Xr cx 4 , -.Xr sppp 4 , -.Xr ifconfig 8 , -.Xr sconfig 8 , -.Xr spppcontrol 8 +.Xr ce 4 , +.Xr netgraph 4 , +.Xr sconfig 8 .Sh HISTORY The .Nm @@ -105,9 +93,3 @@ driver was added in .Fx 5.3 and .Fx 4.11 . -The -.Nm -driver for previous versions of -.Fx -is available from -.Pa http://www.cronyx.ru/ . diff --git a/share/man/man4/netgraph.4 b/share/man/man4/netgraph.4 index bed412193f6b..6d3679041e5c 100644 --- a/share/man/man4/netgraph.4 +++ b/share/man/man4/netgraph.4 @@ -1454,7 +1454,6 @@ common networking problems, solved using .Xr ng_rfc1490 4 , .Xr ng_socket 4 , .Xr ng_split 4 , -.Xr ng_sppp 4 , .Xr ng_sscfu 4 , .Xr ng_sscop 4 , .Xr ng_tee 4 , diff --git a/share/man/man4/ng_sppp.4 b/share/man/man4/ng_sppp.4 deleted file mode 100644 index 685d45f1500e..000000000000 --- a/share/man/man4/ng_sppp.4 +++ /dev/null @@ -1,172 +0,0 @@ -.\" Copyright (C) 2003-2004 Cronyx Engineering. -.\" Copyright (C) 2003-2004 Roman Kurakin -.\" -.\" This software is distributed with NO WARRANTIES, not even the implied -.\" warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -.\" -.\" Authors grant any other persons or organisations a permission to use, -.\" modify and redistribute this software in source and binary forms, -.\" as long as this message is kept with the software, all derivative -.\" works or modified versions. -.\" -.\" Cronyx Id: ng_sppp.4,v 1.1.2.3 2004/03/30 14:28:34 rik Exp $ -.\" $FreeBSD$ -.\" -.Dd February 3, 2005 -.Dt NG_SPPP 4 -.Os -.Sh NAME -.Nm ng_sppp -.Nd sppp netgraph node type -.Sh SYNOPSIS -.In netgraph/ng_sppp.h -.Sh DESCRIPTION -An -.Nm sppp -node is a -.Xr netgraph 4 -interface to the original -.Xr sppp 4 -network module for synchronous lines. -Currently, -.Xr sppp 4 -supports PPP and Cisco HDLC protocols. -An -.Nm sppp -node could be considered as an alternative kernel mode PPP -implementation to -.Pa net/mpd -port + -.Xr ng_ppp 4 , -and as an alternative to -.Xr ng_cisco 4 -node. -While having less features than -.Pa net/mpd -+ -.Xr ng_ppp 4 , -it is significantly easier to use in the majority of simple configurations, -and allows the administrator to not install the -.Pa net/mpd -port. -With -.Nm sppp -you do not need any other nodes, not even an -.Xr ng_iface 4 -node. -When an -.Nm sppp -node is created, a new interface appears which is accessible via -.Xr ifconfig 8 . -Network interfaces corresponding to -.Nm sppp -nodes are named -.Li sppp0 , sppp1 , -etc. -When a node is shut down, the corresponding interface is removed, -and the interface name becomes available for reuse by future -.Nm sppp -nodes. -New nodes always take the first unused interface. -The node itself is assigned the same name as its interface, unless the name -already exists, in which case the node remains unnamed. -The -.Nm sppp -node allows drivers written to the old -.Xr sppp 4 -interface to be rewritten using the -newer more powerful -.Xr netgraph 4 -interface, and still behave in a compatible manner without supporting both -network modules. -.Pp -An -.Nm sppp -node has a single hook named -.Va downstream . -Usually it is connected directly to -a device driver hook. -.Pp -The -.Nm sppp -nodes support the Berkeley Packet Filter, -.Xr bpf 4 . -.Sh HOOKS -This node type supports the following hooks: -.Bl -tag -width ".Va downstream" -.It Va downstream -The connection to the synchronous line. -.El -.Sh CONTROL MESSAGES -This node type supports the generic control messages, plus the following: -.Bl -tag -width foo -.It Dv NGM_SPPP_GET_IFNAME Pq Ic getifname -Returns the name of the associated interface as a -.Dv NUL Ns -terminated -.Tn ASCII -string. -Normally this is the same as the name of the node. -.El -.Sh SHUTDOWN -This node shuts down upon receipt of a -.Dv NGM_SHUTDOWN -control message. -The associated interface is removed and becomes available -for use by future -.Nm sppp -nodes. -.Pp -Unlike most other node types and like -.Xr ng_iface 4 -does, an -.Nm sppp -node does -.Em not -go away when all hooks have been disconnected; rather, an explicit -.Dv NGM_SHUTDOWN -control message is required. -.Sh EXAMPLES -For example, if you have the -.Xr cx 4 -device, you could run PPP over it with just one command: -.Pp -.Dl "ngctl mkpeer cx0: sppp rawdata downstream" -.Pp -Now you have the -.Li sppp0 -interface (if this was the first -.Nm sppp -node) which can be -accessed via -.Xr ifconfig 8 -as a normal network interface, -or via -.Xr spppcontrol 8 -as an -.Xr sppp 4 -interface. -.Sh SEE ALSO -.Xr bpf 4 , -.Xr cx 4 , -.Xr netgraph 4 , -.Xr ng_cisco 4 , -.Xr ng_iface 4 , -.Xr ng_ppp 4 , -.Xr sppp 4 , -.Xr ifconfig 8 , -.Xr ngctl 8 , -.Xr spppcontrol 8 -.Pp -For complex networking topologies you may want to look at -.Pa net/mpd -port. -.Sh HISTORY -The -.Nm sppp -node type was implemented for -.Fx 5.0 . -It was included to the system since -.Fx 5.3 . -.Sh AUTHORS -Copyright (C) 2003-2004 -.An Roman Kurakin Aq Mt rik@cronyx.ru diff --git a/share/man/man4/sppp.4 b/share/man/man4/sppp.4 deleted file mode 100644 index 0420bb45ab80..000000000000 --- a/share/man/man4/sppp.4 +++ /dev/null @@ -1,238 +0,0 @@ -.\" -.\" Copyright (c) 1997, 2001 Joerg Wunsch -.\" -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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. -.\" -.\" $FreeBSD$ -.\" -.Dd May 25, 2008 -.Dt SPPP 4 -.Os -.Sh NAME -.Nm sppp -.Nd point to point protocol network layer for synchronous lines -.Sh SYNOPSIS -.Cd "device sppp" -.Sh DESCRIPTION -The -.Nm -network layer implements the state machine and the Link Control -Protocol (LCP) of the -.Em point to point protocol (PPP) -as described in RFC 1661. -Note that this layer does not provide -network interfaces of its own, it is rather intended to be layered on -top of drivers providing a synchronous point-to-point connection that -wish to run a PPP stack over it. -The corresponding network interfaces -have to be provided by these hardware drivers. -.Pp -The -.Nm -layer provides three basic modes of operation. -The default mode, -with no special flags to be set, is to create the PPP connection -(administrative -.Em Open -event to the LCP layer) as soon as the interface is taken up with the -.Xr ifconfig 8 -command. -Taking the interface down again will terminate the LCP layer -and thus all other layers on top. -The link will also terminate itself as -soon as no Network Control Protocol (NCP) is open anymore, indicating -that the lower layers are no longer needed. -.Pp -Setting the link-level flag -.Em link0 -with -.Xr ifconfig 8 -will cause the respective network interface to go into -.Em passive -mode. -This means, the administrative -.Em Open -event to the LCP layer will be delayed until after the lower layers -signals an -.Em Up -event (rise of -.Dq carrier ) . -This can be used by lower layers to support -a dialin connection where the physical layer is not available -immediately at startup, but only after some external event arrives. -Receipt of a -.Em Down -event from the lower layer will not take the interface completely down -in this case. -.Pp -Finally, setting the flag -.Em link1 -will cause the interface to operate in -.Em dial-on-demand -mode. -This is also only useful if the lower layer supports the notion -of a carrier. -Upon configuring the -respective interface, it will delay the administrative -.Em Open -event to the LCP layer until either an outbound network packet -arrives, or until the lower layer signals an -.Em Up -event, indicating an inbound connection. -As with passive mode, receipt -of a -.Em Down -event (loss of carrier) will not automatically take the interface down, -thus it remains available for further connections. -.Pp -The -.Nm -layer supports the -.Em debug -interface flag that can be set with -.Xr ifconfig 8 . -If this flag is set, the various control protocol packets being -exchanged as well as the option negotiation between both ends of the -link will be logged at level -.Dv LOG_DEBUG . -This can be helpful to examine configuration problems during the first -attempts to set up a new configuration. -Without this flag being set, -only the major phase transitions will be logged at level -.Dv LOG_INFO . -.Pp -It is possible to leave the local interface IP address open for -negotiation by setting it to 0.0.0.0. -This requires that the remote -peer can correctly supply a value for it based on the identity of the -caller, or on the remote address supplied by this side. -Due to the -way the IPCP option negotiation works, this address is being supplied -late during the negotiation, which might cause the remote peer to make -wrong assumptions. -.Pp -In a similar spirit the remote address can be set to the magical -value -.Li 0.0.0. Ns Em * -which means that we do not care what address the remote -side will use, as long as it is not 0.0.0.0. -This is useful if your ISP has several dial-in -servers. -You can of course -.Nm route Cm add Ar something_or_other 0.0.0. Ns Em * -and it will do exactly what you would want it to. -.Pp -The PAP and CHAP authentication protocols as described in RFC 1334, -and RFC 1994 resp., are also implemented. -Their parameters are being -controlled by the -.Xr spppcontrol 8 -utility. -.Pp -VJ header compression is implemented, and enabled by default. -It can be -disabled using -.Xr spppcontrol 8 . -.Sh DIAGNOSTICS -.Bl -diag -.It : illegal in state -An event happened that should not happen for the current state -the respective control protocol is in. -See RFC 1661 for a description -of the state automaton. -.It : loopback -The state automaton detected a line loopback (that is, it was talking -with itself). -The interface will be temporarily disabled. -.It : up -The LCP layer is running again, after a line loopback had previously -been detected. -.It : down -The keepalive facility detected the line being unresponsive. -Keepalive must be explicitly requested by the lower layers in order to -take place. -.El -.Sh SEE ALSO -.Xr inet 4 , -.Xr intro 4 , -.Xr ifconfig 8 , -.Xr spppcontrol 8 -.Rs -.%A W. Simpson, Editor -.%T "The Point-to-Point Protocol (PPP)" -.%O RFC 1661 -.Re -.Rs -.%A G. McGregor -.%T "The PPP Internet Protocol Control Protocol (IPCP)" -.%O RFC 1332 -.Re -.Rs -.%A B. Lloyd -.%A W. Simpson -.%T "PPP Authentication Protocols" -.%O RFC 1334 -.Re -.Rs -.%A W. Simpson -.%T "PPP Challenge Handshake Authentication Protocol (CHAP)" -.%O RFC 1994 -.Re -.Sh AUTHORS -.An -nosplit -The original implementation of -.Nm -was written in 1994 at Cronyx Ltd., Moscow by -.An Serge Vakulenko Aq Mt vak@cronyx.ru . -.An J\(:org Wunsch Aq Mt joerg_wunsch@uriah.heep.sax.de -rewrote a large part in 1997 in order -to fully implement the state machine as described in RFC 1661, so it -could also be used for dialup lines. -He also wrote this man page. -Serge later on wrote a basic implementation for PAP and CHAP, which -served as the base for the current implementation, done again by -.An J\(:org Wunsch . -.Sh BUGS -Many. -.Pp -Currently, only the -.Em IPCP -control protocol and -.Xr ip 4 -network protocol is supported. -More NCPs should be implemented, as well as other control protocols -for authentication and link quality reporting. -.Pp -Negotiation loop avoidance is not fully implemented. -If the negotiation -does not converge, this can cause an endless loop. -.Pp -The various parameters that should be adjustable per RFC 1661 are -currently hard-coded into the kernel, and should be made accessible -through -.Xr spppcontrol 8 . -.Pp -.Em Passive -mode has not been tested extensively. -.Pp -Link-level compression protocols should be supported. diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index 6cff3f12954a..8f247c480cc7 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -1941,21 +1941,6 @@ ifconfig_gif0="inet 10.0.0.1 10.0.0.2 netmask 255.255.255.252" gifconfig_gif1="inet6 2a00::1 2a01::1" ifconfig_gif1="inet 10.1.0.1 10.1.0.2 netmask 255.255.255.252" .Ed -.It Va sppp_interfaces -.Pq Vt str -Set to the list of -.Xr sppp 4 -interfaces to configure on this host. -A -.Va spppconfig_ Ns Aq Ar interface -variable is assumed to exist for each value of -.Ar interface . -Each interface should also be configured by a general -.Va ifconfig_ Ns Aq Ar interface -setting. -Refer to -.Xr spppcontrol 8 -for more information about available options. .It Va ppp_enable .Pq Vt bool If set to diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 39446fba06b3..722da321500b 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -810,7 +810,6 @@ options NETGRAPH_PRED1 options NETGRAPH_RFC1490 options NETGRAPH_SOCKET options NETGRAPH_SPLIT -options NETGRAPH_SPPP options NETGRAPH_TAG options NETGRAPH_TCPMSS options NETGRAPH_TEE @@ -875,10 +874,6 @@ device wlan_xauth device wlan_acl device wlan_amrr -# The `sppp' device serves a similar role for certain types -# of synchronous PPP links (like `cx', `ar'). -device sppp - # The `bpf' device enables the Berkeley Packet Filter. Be # aware of the legal and administrative consequences of enabling this # option. DHCP requires bpf. diff --git a/sys/conf/files b/sys/conf/files index fd91666f3718..ce1e0cb97362 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -4157,8 +4157,6 @@ net/if_llatbl.c standard net/if_me.c optional me inet net/if_media.c standard net/if_mib.c standard -net/if_spppfr.c optional sppp | netgraph_sppp -net/if_spppsubr.c optional sppp | netgraph_sppp net/if_stf.c optional stf inet inet6 net/if_tuntap.c optional tuntap net/if_vlan.c optional vlan @@ -4192,8 +4190,7 @@ net/route/route_tables.c standard net/route/route_temporal.c standard net/rss_config.c optional inet rss | inet6 rss net/rtsock.c standard -net/slcompress.c optional netgraph_vjc | sppp | \ - netgraph_sppp +net/slcompress.c optional netgraph_vjc net/toeplitz.c optional inet rss | inet6 rss | route_mpath net/vnet.c optional vimage net80211/ieee80211.c optional wlan @@ -4316,7 +4313,6 @@ netgraph/ng_pred1.c optional netgraph_pred1 netgraph/ng_rfc1490.c optional netgraph_rfc1490 netgraph/ng_socket.c optional netgraph_socket netgraph/ng_split.c optional netgraph_split -netgraph/ng_sppp.c optional netgraph_sppp netgraph/ng_tag.c optional netgraph_tag netgraph/ng_tcpmss.c optional netgraph_tcpmss netgraph/ng_tee.c optional netgraph_tee diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index e22ce97eee4f..e83bcd5a3492 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -33,9 +33,6 @@ dev/ce/ceddk.c optional ce dev/ce/if_ce.c optional ce dev/ce/tau32-ddk.c optional ce \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION} ${NO_WMISLEADING_INDENTATION}" -dev/cp/cpddk.c optional cp \ - compile-with "${NORMAL_C} ${NO_WMISLEADING_INDENTATION}" -dev/cp/if_cp.c optional cp dev/glxiic/glxiic.c optional glxiic dev/glxsb/glxsb.c optional glxsb dev/glxsb/glxsb_hash.c optional glxsb diff --git a/sys/conf/files.x86 b/sys/conf/files.x86 index 19c7dabd6001..5018a52673e3 100644 --- a/sys/conf/files.x86 +++ b/sys/conf/files.x86 @@ -79,6 +79,9 @@ dev/bxe/57710_init_values.c optional bxe pci dev/bxe/57711_init_values.c optional bxe pci dev/bxe/57712_init_values.c optional bxe pci dev/coretemp/coretemp.c optional coretemp +dev/cp/cpddk.c optional cp \ + compile-with "${NORMAL_C} ${NO_WMISLEADING_INDENTATION}" +dev/cp/if_cp.c optional cp dev/cpuctl/cpuctl.c optional cpuctl dev/dpms/dpms.c optional dpms dev/fb/fb.c optional fb | vga diff --git a/sys/conf/options.i386 b/sys/conf/options.i386 index 5e7ea446089b..37b112e1e6e9 100644 --- a/sys/conf/options.i386 +++ b/sys/conf/options.i386 @@ -88,9 +88,6 @@ ATKBD_DFLT_KEYMAP opt_atkbd.h # Video spigot SPIGOT_UNSECURE opt_spigot.h -# Enables NETGRAPH support for Cronyx adapters -NETGRAPH_CRONYX opt_ng_cronyx.h - # Device options DEV_APIC opt_apic.h DEV_ATPIC opt_atpic.h diff --git a/sys/dev/ce/if_ce.c b/sys/dev/ce/if_ce.c index 486397d2a2a9..4bd0070f8a56 100644 --- a/sys/dev/ce/if_ce.c +++ b/sys/dev/ce/if_ce.c @@ -38,42 +38,18 @@ __FBSDID("$FreeBSD$"); #include #include #include -# include -# include +#include +#include #include #include -#include "opt_ng_cronyx.h" -#ifdef NETGRAPH_CRONYX -# include "opt_netgraph.h" -# ifndef NETGRAPH -# error #option NETGRAPH missed from configuration -# endif -# include -# include -# include -#else -# include -# include -# define PP_CISCO IFF_LINK2 -# include -#endif +#include +#include +#include #include #include -#include +#include #include -/* If we don't have Cronyx's sppp version, we don't have fr support via sppp */ -#ifndef PP_FR -#define PP_FR 0 -#endif - -#ifndef IFP2SP -#define IFP2SP(ifp) ((struct sppp*)ifp) -#endif -#ifndef SP2IFP -#define SP2IFP(sp) ((struct ifnet*)sp) -#endif - #ifndef PCIR_BAR #define PCIR_BAR(x) (PCIR_MAPS + (x) * 4) #endif @@ -88,26 +64,6 @@ __FBSDID("$FreeBSD$"); #define CE_DEBUG2(d,s) ({if (d->chan->debug>1) {\ printf ("%s: ", d->name); printf s;}}) -#ifndef IF_DRAIN -#define IF_DRAIN(ifq) do { \ - struct mbuf *m; \ - for (;;) { \ - IF_DEQUEUE(ifq, m); \ - if (m == NULL) \ - break; \ - m_freem(m); \ - } \ -} while (0) -#endif - -#ifndef _IF_QLEN -#define _IF_QLEN(ifq) ((ifq)->ifq_len) -#endif - -#ifndef callout_drain -#define callout_drain callout_stop -#endif - #define CE_LOCK_NAME "ceX" #define CE_LOCK(_bd) mtx_lock (&(_bd)->ce_mtx) @@ -143,16 +99,12 @@ typedef struct _drv_t { ce_board_t *board; ce_chan_t *chan; struct ifqueue rqueue; -#ifdef NETGRAPH - char nodename [NG_NODESIZE]; + char nodename [NG_NODESIZ]; hook_p hook; hook_p debug_hook; node_p node; struct ifqueue queue; struct ifqueue hi_queue; -#else - struct ifnet *ifp; -#endif short timeout; struct callout timeout_handle; struct cdev *devt; @@ -185,15 +137,7 @@ static void ce_start (drv_t *d); static void ce_down (drv_t *d); static void ce_watchdog (drv_t *d); static void ce_watchdog_timer (void *arg); -#ifdef NETGRAPH -extern struct ng_type typestruct; -#else -static void ce_ifstart (struct ifnet *ifp); -static void ce_tlf (struct sppp *sp); -static void ce_tls (struct sppp *sp); -static int ce_sioctl (struct ifnet *ifp, u_long cmd, caddr_t data); -static void ce_initialize (void *softc); -#endif +static struct ng_type typestruct; static ce_board_t *adapter [NBRD]; static drv_t *channel [NBRD*NCHAN]; @@ -301,9 +245,8 @@ static void ce_intr (void *arg) ce_board_t *b = bd->board; int s; int i; -#if __FreeBSD_version >= 500000 && defined NETGRAPH int error; -#endif + s = splimp (); if (ce_destroy) { splx (s); @@ -330,15 +273,11 @@ static void ce_intr (void *arg) IF_DEQUEUE (&d->rqueue,m); if (!m) continue; -#ifdef NETGRAPH if (d->hook) { NG_SEND_DATA_ONLY (error, d->hook, m); } else { IF_DRAIN (&d->rqueue); } -#else - sppp_input (d->ifp, m); -#endif } } } @@ -534,7 +473,6 @@ static int ce_attach (device_t dev) d = c->sys; callout_init (&d->timeout_handle, 1); -#ifdef NETGRAPH if (ng_make_node_common (&typestruct, &d->node) != 0) { printf ("%s: cannot make common node\n", d->name); d->node = NULL; @@ -554,29 +492,6 @@ static int ce_attach (device_t dev) mtx_init (&d->queue.ifq_mtx, "ce_queue", NULL, MTX_DEF); mtx_init (&d->hi_queue.ifq_mtx, "ce_queue_hi", NULL, MTX_DEF); mtx_init (&d->rqueue.ifq_mtx, "ce_rqueue", NULL, MTX_DEF); -#else /*NETGRAPH*/ - d->ifp = if_alloc(IFT_PPP); - if (!d->ifp) { - printf ("%s: cannot if_alloc() interface\n", d->name); - continue; - } - d->ifp->if_softc = d; - if_initname (d->ifp, "ce", b->num * NCHAN + c->num); - d->ifp->if_mtu = PP_MTU; - d->ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; - d->ifp->if_ioctl = ce_sioctl; - d->ifp->if_start = ce_ifstart; - d->ifp->if_init = ce_initialize; - d->rqueue.ifq_maxlen = ifqmaxlen; - mtx_init (&d->rqueue.ifq_mtx, "ce_rqueue", NULL, MTX_DEF); - sppp_attach (d->ifp); - if_attach (d->ifp); - IFP2SP(d->ifp)->pp_tlf = ce_tlf; - IFP2SP(d->ifp)->pp_tls = ce_tls; - /* If BPF is in the kernel, call the attach for it. - * The header size of PPP or Cisco/HDLC is 4 bytes. */ - bpfattach (d->ifp, DLT_PPP, 4); -#endif /*NETGRAPH*/ ce_start_chan (c, 1, 1, d->dmamem.virt, d->dmamem.phys); /* Register callback functions. */ @@ -635,20 +550,6 @@ static int ce_detach (device_t dev) if (! d || ! d->chan) continue; callout_stop (&d->timeout_handle); -#ifndef NETGRAPH - /* Detach from the packet filter list of interfaces. */ - bpfdetach (d->ifp); - - /* Detach from the sync PPP list. */ - sppp_detach (d->ifp); - - /* Detach from the system list of interfaces. */ - if_detach (d->ifp); - if_free(d->ifp); - - IF_DRAIN (&d->rqueue); - mtx_destroy (&d->rqueue.ifq_mtx); -#else if (d->node) { ng_rmnode_self (d->node); NG_NODE_UNREF (d->node); @@ -658,7 +559,6 @@ static int ce_detach (device_t dev) mtx_destroy (&d->queue.ifq_mtx); mtx_destroy (&d->hi_queue.ifq_mtx); mtx_destroy (&d->rqueue.ifq_mtx); -#endif destroy_dev (d->devt); } @@ -690,91 +590,6 @@ static int ce_detach (device_t dev) return 0; } -#ifndef NETGRAPH -static void ce_ifstart (struct ifnet *ifp) -{ - drv_t *d = ifp->if_softc; - bdrv_t *bd = d->board->sys; - - CE_LOCK (bd); - ce_start (d); - CE_UNLOCK (bd); -} - -static void ce_tlf (struct sppp *sp) -{ - drv_t *d = SP2IFP(sp)->if_softc; - - CE_DEBUG2 (d, ("ce_tlf\n")); - sp->pp_down (sp); -} - -static void ce_tls (struct sppp *sp) -{ - drv_t *d = SP2IFP(sp)->if_softc; - - CE_DEBUG2 (d, ("ce_tls\n")); - sp->pp_up (sp); -} - -/* - * Process an ioctl request. - */ -static int ce_sioctl (struct ifnet *ifp, u_long cmd, caddr_t data) -{ - drv_t *d = ifp->if_softc; - bdrv_t *bd = d->board->sys; - int error, s, was_up, should_be_up; - - was_up = (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0; - error = sppp_ioctl (ifp, cmd, data); - - if (error) - return error; - - if (! (ifp->if_flags & IFF_DEBUG)) - d->chan->debug = 0; - else - d->chan->debug = d->chan->debug_shadow; - - switch (cmd) { - default: CE_DEBUG2 (d, ("ioctl 0x%lx\n", cmd)); return 0; - case SIOCADDMULTI: CE_DEBUG2 (d, ("ioctl SIOCADDMULTI\n")); return 0; - case SIOCDELMULTI: CE_DEBUG2 (d, ("ioctl SIOCDELMULTI\n")); return 0; - case SIOCSIFFLAGS: CE_DEBUG2 (d, ("ioctl SIOCSIFFLAGS\n")); break; - case SIOCSIFADDR: CE_DEBUG2 (d, ("ioctl SIOCSIFADDR\n")); break; - } - - /* We get here only in case of SIFFLAGS or SIFADDR. */ - s = splimp (); - CE_LOCK (bd); - should_be_up = (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0; - if (! was_up && should_be_up) { - /* Interface goes up -- start it. */ - ce_up (d); - ce_start (d); - } else if (was_up && ! should_be_up) { - /* Interface is going down -- stop it. */ -/* if ((IFP2SP(ifp)->pp_flags & PP_FR) || (ifp->if_flags & PP_CISCO))*/ - ce_down (d); - } - CE_DEBUG (d, ("ioctl 0x%lx p4\n", cmd)); - CE_UNLOCK (bd); - splx (s); - return 0; -} - -/* - * Initialization of interface. - * It seems to be never called by upper level? - */ -static void ce_initialize (void *softc) -{ - drv_t *d = softc; - - CE_DEBUG (d, ("ce_initialize\n")); -} -#endif /*NETGRAPH*/ /* * Stop the interface. Called on splimp(). @@ -820,18 +635,11 @@ static void ce_send (drv_t *d) while (ce_transmit_space (d->chan)) { /* Get the packet to send. */ -#ifdef NETGRAPH IF_DEQUEUE (&d->hi_queue, m); if (! m) IF_DEQUEUE (&d->queue, m); -#else - m = sppp_dequeue (d->ifp); -#endif if (! m) return; -#ifndef NETGRAPH - BPF_MTAP (d->ifp, m); -#endif len = m_length (m, NULL); if (len >= BUFSZ) printf ("%s: too long packet: %d bytes: ", @@ -847,9 +655,6 @@ static void ce_send (drv_t *d) /* Set up transmit timeout, if the transmit ring is not empty.*/ d->timeout = 10; } -#ifndef NETGRAPH - d->ifp->if_flags |= IFF_DRV_OACTIVE; -#endif } /* @@ -906,10 +711,6 @@ static void ce_transmit (ce_chan_t *c, void *attachment, int len) drv_t *d = c->sys; d->timeout = 0; -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_OPACKETS, 1); - d->ifp->if_flags &= ~IFF_DRV_OACTIVE; -#endif ce_start (d); } @@ -924,24 +725,12 @@ static void ce_receive (ce_chan_t *c, unsigned char *data, int len) m = makembuf (data, len); if (! m) { CE_DEBUG (d, ("no memory for packet\n")); -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_IQDROPS, 1); -#endif return; } if (c->debug > 1) m_print (m, 0); -#ifdef NETGRAPH m->m_pkthdr.rcvif = 0; IF_ENQUEUE(&d->rqueue, m); -#else - if_inc_counter(d->ifp, IFCOUNTER_IPACKETS, 1); - m->m_pkthdr.rcvif = d->ifp; - /* Check if there's a BPF listener on this interface. - * If so, hand off the raw packet to bpf. */ - BPF_MTAP(d->ifp, m); - IF_ENQUEUE(&d->rqueue, m); -#endif } static void ce_error (ce_chan_t *c, int data) @@ -951,36 +740,19 @@ static void ce_error (ce_chan_t *c, int data) switch (data) { case CE_FRAME: CE_DEBUG (d, ("frame error\n")); -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_IERRORS, 1); -#endif break; case CE_CRC: CE_DEBUG (d, ("crc error\n")); -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_IERRORS, 1); -#endif break; case CE_OVERRUN: CE_DEBUG (d, ("overrun error\n")); -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_COLLISIONS, 1); - if_inc_counter(d->ifp, IFCOUNTER_IERRORS, 1); -#endif break; case CE_OVERFLOW: CE_DEBUG (d, ("overflow error\n")); -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_IERRORS, 1); -#endif break; case CE_UNDERRUN: CE_DEBUG (d, ("underrun error\n")); d->timeout = 0; -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_OERRORS, 1); - d->ifp->if_flags &= ~IFF_DRV_OACTIVE; -#endif ce_start (d); break; default: @@ -1054,65 +826,6 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc bcopy (mask, data, sizeof (mask)); return 0; -#ifndef NETGRAPH - case SERIAL_GETPROTO: - CE_DEBUG2 (d, ("ioctl: getproto\n")); - strcpy ((char*)data, (IFP2SP(d->ifp)->pp_flags & PP_FR) ? "fr" : - (d->ifp->if_flags & PP_CISCO) ? "cisco" : "ppp"); - return 0; - - case SERIAL_SETPROTO: - CE_DEBUG2 (d, ("ioctl: setproto\n")); - /* Only for superuser! */ - error = priv_check (td, PRIV_DRIVER); - if (error) - return error; - if (d->ifp->if_flags & IFF_DRV_RUNNING) - return EBUSY; - if (! strcmp ("cisco", (char*)data)) { - IFP2SP(d->ifp)->pp_flags &= ~(PP_FR); - IFP2SP(d->ifp)->pp_flags |= PP_KEEPALIVE; - d->ifp->if_flags |= PP_CISCO; -#if PP_FR != 0 - } else if (! strcmp ("fr", (char*)data)) { - d->ifp->if_flags &= ~(PP_CISCO); - IFP2SP(d->ifp)->pp_flags |= PP_FR | PP_KEEPALIVE; -#endif - } else if (! strcmp ("ppp", (char*)data)) { - IFP2SP(d->ifp)->pp_flags &= ~PP_FR; - IFP2SP(d->ifp)->pp_flags &= ~PP_KEEPALIVE; - d->ifp->if_flags &= ~(PP_CISCO); - } else - return EINVAL; - return 0; - - case SERIAL_GETKEEPALIVE: - CE_DEBUG2 (d, ("ioctl: getkeepalive\n")); - if ((IFP2SP(d->ifp)->pp_flags & PP_FR) || - (d->ifp->if_flags & PP_CISCO)) - return EINVAL; - *(int*)data = (IFP2SP(d->ifp)->pp_flags & PP_KEEPALIVE) ? 1 : 0; - return 0; - - case SERIAL_SETKEEPALIVE: - CE_DEBUG2 (d, ("ioctl: setkeepalive\n")); - /* Only for superuser! */ - error = priv_check (td, PRIV_DRIVER); - if (error) - return error; - if ((IFP2SP(d->ifp)->pp_flags & PP_FR) || - (d->ifp->if_flags & PP_CISCO)) - return EINVAL; - s = splimp (); - CE_LOCK (bd); - if (*(int*)data) - IFP2SP(d->ifp)->pp_flags |= PP_KEEPALIVE; - else - IFP2SP(d->ifp)->pp_flags &= ~PP_KEEPALIVE; - CE_UNLOCK (bd); - splx (s); - return 0; -#endif /*NETGRAPH*/ case SERIAL_GETMODE: CE_DEBUG2 (d, ("ioctl: getmode\n")); @@ -1304,18 +1017,7 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc error = priv_check (td, PRIV_DRIVER); if (error) return error; -#ifndef NETGRAPH - /* - * The debug_shadow is always greater than zero for logic - * simplicity. For switching debug off the IFF_DEBUG is - * responsible. - */ - d->chan->debug_shadow = (*(int*)data) ? (*(int*)data) : 1; - if (d->ifp->if_flags & IFF_DEBUG) - d->chan->debug = d->chan->debug_shadow; -#else d->chan->debug = *(int*)data; -#endif return 0; case SERIAL_GETBAUD: @@ -1651,7 +1353,6 @@ static int ce_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc return ENOTTY; } -#ifdef NETGRAPH static int ng_ce_constructor (node_p node) { drv_t *d = NG_NODE_PRIVATE (node); @@ -2059,7 +1760,6 @@ static int ng_ce_disconnect (hook_p hook) } return 0; } -#endif static int ce_modevent (module_t mod, int type, void *unused) { @@ -2068,10 +1768,8 @@ static int ce_modevent (module_t mod, int type, void *unused) switch (type) { case MOD_LOAD: -#if __FreeBSD_version >= 500000 && defined NETGRAPH if (ng_newtype (&typestruct)) printf ("Failed to register ng_ce\n"); -#endif ++load_count; callout_init (&timeout_handle, 1); callout_reset (&timeout_handle, hz*5, ce_timeout, 0); @@ -2079,9 +1777,7 @@ static int ce_modevent (module_t mod, int type, void *unused) case MOD_UNLOAD: if (load_count == 1) { printf ("Removing device entry for Tau32-PCI\n"); -#if __FreeBSD_version >= 500000 && defined NETGRAPH ng_rmtype (&typestruct); -#endif } /* If we were wait it than it reasserted now, just stop it. * Actually we shouldn't get this condition. But code could be @@ -2097,7 +1793,6 @@ static int ce_modevent (module_t mod, int type, void *unused) return 0; } -#ifdef NETGRAPH static struct ng_type typestruct = { .version = NG_ABI_VERSION, .name = NG_CE_NODE_TYPE, @@ -2110,13 +1805,8 @@ static struct ng_type typestruct = { .disconnect = ng_ce_disconnect, }; -#endif /*NETGRAPH*/ -#ifdef NETGRAPH MODULE_DEPEND (ng_ce, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION); -#else -MODULE_DEPEND (ce, sppp, 1, 1, 1); -#endif #ifdef KLD_MODULE DRIVER_MODULE (cemod, pci, ce_driver, ce_devclass, ce_modevent, NULL); #else diff --git a/sys/dev/ce/ng_ce.h b/sys/dev/ce/ng_ce.h index b8e9604c4f5e..d466197647c1 100644 --- a/sys/dev/ce/ng_ce.h +++ b/sys/dev/ce/ng_ce.h @@ -16,8 +16,6 @@ * $FreeBSD$ */ -#ifdef NETGRAPH - #ifndef _CE_NETGRAPH_H_ #define _CE_NETGRAPH_H_ @@ -27,5 +25,3 @@ #define NG_CE_HOOK_DEBUG "debug" #endif /* _CE_NETGRAPH_H_ */ - -#endif /* NETGRAPH */ diff --git a/sys/i386/include/cserial.h b/sys/dev/cp/cserial.h similarity index 100% rename from sys/i386/include/cserial.h rename to sys/dev/cp/cserial.h diff --git a/sys/dev/cp/if_cp.c b/sys/dev/cp/if_cp.c index c8d080fcc601..d2f7fa58b02f 100644 --- a/sys/dev/cp/if_cp.c +++ b/sys/dev/cp/if_cp.c @@ -47,32 +47,14 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include "opt_ng_cronyx.h" -#ifdef NETGRAPH_CRONYX -# include "opt_netgraph.h" -# ifndef NETGRAPH -# error #option NETGRAPH missed from configuration -# endif -# include -# include -# include -#else -# include -# include -#include -# define PP_CISCO IFF_LINK2 -# include -#endif +#include +#include +#include #include #include -#include +#include #include -/* If we don't have Cronyx's sppp version, we don't have fr support via sppp */ -#ifndef PP_FR -#define PP_FR 0 -#endif - #define CP_DEBUG(d,s) ({if (d->chan->debug) {\ printf ("%s: ", d->name); printf s;}}) #define CP_DEBUG2(d,s) ({if (d->chan->debug>1) {\ @@ -110,17 +92,12 @@ typedef struct _drv_t { cp_chan_t *chan; cp_board_t *board; cp_dma_mem_t dmamem; -#ifdef NETGRAPH - char nodename [NG_NODESIZE]; + char nodename [NG_NODESIZ]; hook_p hook; hook_p debug_hook; node_p node; struct ifqueue queue; struct ifqueue hi_queue; -#else - struct ifqueue queue; - struct ifnet *ifp; -#endif short timeout; struct callout timeout_handle; struct cdev *devt; @@ -152,15 +129,7 @@ static void cp_start (drv_t *d); static void cp_down (drv_t *d); static void cp_watchdog (drv_t *d); static void cp_watchdog_timer (void *arg); -#ifdef NETGRAPH -extern struct ng_type typestruct; -#else -static void cp_ifstart (struct ifnet *ifp); -static void cp_tlf (struct sppp *sp); -static void cp_tls (struct sppp *sp); -static int cp_sioctl (struct ifnet *ifp, u_long cmd, caddr_t data); -static void cp_initialize (void *softc); -#endif +static struct ng_type typestruct; static cp_board_t *adapter [NBRD]; static drv_t *channel [NBRD*NCHAN]; @@ -274,9 +243,6 @@ static void cp_intr (void *arg) { bdrv_t *bd = arg; cp_board_t *b = bd->board; -#ifndef NETGRAPH - int i; -#endif int s = splimp (); if (cp_destroy) { splx (s); @@ -300,21 +266,6 @@ static void cp_intr (void *arg) CP_UNLOCK (bd); splx (s); -#ifndef NETGRAPH - /* Pass packets in a lock-free state */ - for (i = 0; i < NCHAN && b->chan[i].type; i++) { - drv_t *d = b->chan[i].sys; - struct mbuf *m; - if (!d || !d->running) - continue; - while (_IF_QLEN(&d->queue)) { - IF_DEQUEUE (&d->queue,m); - if (!m) - continue; - sppp_input (d->ifp, m); - } - } -#endif } static void @@ -474,7 +425,6 @@ static int cp_attach (device_t dev) d->chan = c; c->sys = d; callout_init (&d->timeout_handle, 1); -#ifdef NETGRAPH if (ng_make_node_common (&typestruct, &d->node) != 0) { printf ("%s: cannot make common node\n", d->name); d->node = NULL; @@ -492,29 +442,6 @@ static int cp_attach (device_t dev) d->hi_queue.ifq_maxlen = ifqmaxlen; mtx_init (&d->queue.ifq_mtx, "cp_queue", NULL, MTX_DEF); mtx_init (&d->hi_queue.ifq_mtx, "cp_queue_hi", NULL, MTX_DEF); -#else /*NETGRAPH*/ - d->ifp = if_alloc(IFT_PPP); - if (d->ifp == NULL) { - printf ("%s: cannot if_alloc() interface\n", d->name); - continue; - } - d->ifp->if_softc = d; - if_initname (d->ifp, "cp", b->num * NCHAN + c->num); - d->ifp->if_mtu = PP_MTU; - d->ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; - d->ifp->if_ioctl = cp_sioctl; - d->ifp->if_start = cp_ifstart; - d->ifp->if_init = cp_initialize; - d->queue.ifq_maxlen = NRBUF; - mtx_init (&d->queue.ifq_mtx, "cp_queue", NULL, MTX_DEF); - sppp_attach (d->ifp); - if_attach (d->ifp); - IFP2SP(d->ifp)->pp_tlf = cp_tlf; - IFP2SP(d->ifp)->pp_tls = cp_tls; - /* If BPF is in the kernel, call the attach for it. - * The header size of PPP or Cisco/HDLC is 4 bytes. */ - bpfattach (d->ifp, DLT_PPP, 4); -#endif /*NETGRAPH*/ cp_start_e1 (c); cp_start_chan (c, 1, 1, d->dmamem.virt, d->dmamem.phys); @@ -586,19 +513,6 @@ static int cp_detach (device_t dev) if (! d || ! d->chan->type) continue; callout_stop (&d->timeout_handle); -#ifndef NETGRAPH - /* Detach from the packet filter list of interfaces. */ - bpfdetach (d->ifp); - - /* Detach from the sync PPP list. */ - sppp_detach (d->ifp); - - /* Detach from the system list of interfaces. */ - if_detach (d->ifp); - if_free (d->ifp); - IF_DRAIN (&d->queue); - mtx_destroy (&d->queue.ifq_mtx); -#else if (d->node) { ng_rmnode_self (d->node); NG_NODE_UNREF (d->node); @@ -606,7 +520,6 @@ static int cp_detach (device_t dev) } mtx_destroy (&d->queue.ifq_mtx); mtx_destroy (&d->hi_queue.ifq_mtx); -#endif destroy_dev (d->devt); } @@ -639,96 +552,6 @@ static int cp_detach (device_t dev) return 0; } -#ifndef NETGRAPH -static void cp_ifstart (struct ifnet *ifp) -{ - drv_t *d = ifp->if_softc; - bdrv_t *bd = d->board->sys; - - CP_LOCK (bd); - cp_start (d); - CP_UNLOCK (bd); -} - -static void cp_tlf (struct sppp *sp) -{ - drv_t *d = SP2IFP(sp)->if_softc; - - CP_DEBUG2 (d, ("cp_tlf\n")); - /* XXXRIK: Don't forget to protect them by LOCK, or kill them. */ -/* cp_set_dtr (d->chan, 0);*/ -/* cp_set_rts (d->chan, 0);*/ - if (!(sp->pp_flags & PP_FR) && !(d->ifp->if_flags & PP_CISCO)) - sp->pp_down (sp); -} - -static void cp_tls (struct sppp *sp) -{ - drv_t *d = SP2IFP(sp)->if_softc; - - CP_DEBUG2 (d, ("cp_tls\n")); - if (!(sp->pp_flags & PP_FR) && !(d->ifp->if_flags & PP_CISCO)) - sp->pp_up (sp); -} - -/* - * Process an ioctl request. - */ -static int cp_sioctl (struct ifnet *ifp, u_long cmd, caddr_t data) -{ - drv_t *d = ifp->if_softc; - bdrv_t *bd = d->board->sys; - int error, s, was_up, should_be_up; - - was_up = (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0; - error = sppp_ioctl (ifp, cmd, data); - - if (error) - return error; - - if (! (ifp->if_flags & IFF_DEBUG)) - d->chan->debug = 0; - else - d->chan->debug = d->chan->debug_shadow; - - switch (cmd) { - default: CP_DEBUG2 (d, ("ioctl 0x%lx\n", cmd)); return 0; - case SIOCADDMULTI: CP_DEBUG2 (d, ("ioctl SIOCADDMULTI\n")); return 0; - case SIOCDELMULTI: CP_DEBUG2 (d, ("ioctl SIOCDELMULTI\n")); return 0; - case SIOCSIFFLAGS: CP_DEBUG2 (d, ("ioctl SIOCSIFFLAGS\n")); break; - case SIOCSIFADDR: CP_DEBUG2 (d, ("ioctl SIOCSIFADDR\n")); break; - } - - /* We get here only in case of SIFFLAGS or SIFADDR. */ - s = splimp (); - CP_LOCK (bd); - should_be_up = (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0; - if (! was_up && should_be_up) { - /* Interface goes up -- start it. */ - cp_up (d); - cp_start (d); - } else if (was_up && ! should_be_up) { - /* Interface is going down -- stop it. */ -/* if ((IFP2SP(ifp)->pp_flags & PP_FR) || (ifp->if_flags & PP_CISCO))*/ - cp_down (d); - } - CP_DEBUG (d, ("ioctl 0x%lx p4\n", cmd)); - CP_UNLOCK (bd); - splx (s); - return 0; -} - -/* - * Initialization of interface. - * It seems to be never called by upper level? - */ -static void cp_initialize (void *softc) -{ - drv_t *d = softc; - - CP_DEBUG (d, ("cp_initialize\n")); -} -#endif /*NETGRAPH*/ /* * Stop the interface. Called on splimp(). @@ -778,18 +601,11 @@ static void cp_send (drv_t *d) while (cp_transmit_space (d->chan)) { /* Get the packet to send. */ -#ifdef NETGRAPH IF_DEQUEUE (&d->hi_queue, m); if (! m) IF_DEQUEUE (&d->queue, m); -#else - m = sppp_dequeue (d->ifp); -#endif if (! m) return; -#ifndef NETGRAPH - BPF_MTAP (d->ifp, m); -#endif len = m_length (m, NULL); if (len >= BUFSZ) printf ("%s: too long packet: %d bytes: ", @@ -805,9 +621,6 @@ static void cp_send (drv_t *d) /* Set up transmit timeout, if the transmit ring is not empty.*/ d->timeout = 10; } -#ifndef NETGRAPH - d->ifp->if_drv_flags |= IFF_DRV_OACTIVE; -#endif } /* @@ -864,10 +677,6 @@ static void cp_transmit (cp_chan_t *c, void *attachment, int len) drv_t *d = c->sys; d->timeout = 0; -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_OPACKETS, 1); - d->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; -#endif cp_start (d); } @@ -875,9 +684,7 @@ static void cp_receive (cp_chan_t *c, unsigned char *data, int len) { drv_t *d = c->sys; struct mbuf *m; -#ifdef NETGRAPH int error; -#endif if (! d->running) return; @@ -885,24 +692,12 @@ static void cp_receive (cp_chan_t *c, unsigned char *data, int len) m = makembuf (data, len); if (! m) { CP_DEBUG (d, ("no memory for packet\n")); -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_IQDROPS, 1); -#endif return; } if (c->debug > 1) m_print (m, 0); -#ifdef NETGRAPH m->m_pkthdr.rcvif = 0; NG_SEND_DATA_ONLY (error, d->hook, m); -#else - if_inc_counter(d->ifp, IFCOUNTER_IPACKETS, 1); - m->m_pkthdr.rcvif = d->ifp; - /* Check if there's a BPF listener on this interface. - * If so, hand off the raw packet to bpf. */ - BPF_MTAP(d->ifp, m); - IF_ENQUEUE (&d->queue, m); -#endif } static void cp_error (cp_chan_t *c, int data) @@ -912,36 +707,19 @@ static void cp_error (cp_chan_t *c, int data) switch (data) { case CP_FRAME: CP_DEBUG (d, ("frame error\n")); -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_IERRORS, 1); -#endif break; case CP_CRC: CP_DEBUG (d, ("crc error\n")); -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_IERRORS, 1); -#endif break; case CP_OVERRUN: CP_DEBUG (d, ("overrun error\n")); -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_COLLISIONS, 1); - if_inc_counter(d->ifp, IFCOUNTER_IERRORS, 1); -#endif break; case CP_OVERFLOW: CP_DEBUG (d, ("overflow error\n")); -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_IERRORS, 1); -#endif break; case CP_UNDERRUN: CP_DEBUG (d, ("underrun error\n")); d->timeout = 0; -#ifndef NETGRAPH - if_inc_counter(d->ifp, IFCOUNTER_OERRORS, 1); - d->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; -#endif cp_start (d); break; default: @@ -1016,65 +794,6 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc bcopy (mask, data, sizeof (mask)); return 0; -#ifndef NETGRAPH - case SERIAL_GETPROTO: - CP_DEBUG2 (d, ("ioctl: getproto\n")); - strcpy ((char*)data, (IFP2SP(d->ifp)->pp_flags & PP_FR) ? "fr" : - (d->ifp->if_flags & PP_CISCO) ? "cisco" : "ppp"); - return 0; - - case SERIAL_SETPROTO: - CP_DEBUG2 (d, ("ioctl: setproto\n")); - /* Only for superuser! */ - error = priv_check (td, PRIV_DRIVER); - if (error) - return error; - if (d->ifp->if_drv_flags & IFF_DRV_RUNNING) - return EBUSY; - if (! strcmp ("cisco", (char*)data)) { - IFP2SP(d->ifp)->pp_flags &= ~(PP_FR); - IFP2SP(d->ifp)->pp_flags |= PP_KEEPALIVE; - d->ifp->if_flags |= PP_CISCO; -#if PP_FR != 0 - } else if (! strcmp ("fr", (char*)data)) { - d->ifp->if_flags &= ~(PP_CISCO); - IFP2SP(d->ifp)->pp_flags |= PP_FR | PP_KEEPALIVE; -#endif - } else if (! strcmp ("ppp", (char*)data)) { - IFP2SP(d->ifp)->pp_flags &= ~PP_FR; - IFP2SP(d->ifp)->pp_flags &= ~PP_KEEPALIVE; - d->ifp->if_flags &= ~(PP_CISCO); - } else - return EINVAL; - return 0; - - case SERIAL_GETKEEPALIVE: - CP_DEBUG2 (d, ("ioctl: getkeepalive\n")); - if ((IFP2SP(d->ifp)->pp_flags & PP_FR) || - (d->ifp->if_flags & PP_CISCO)) - return EINVAL; - *(int*)data = (IFP2SP(d->ifp)->pp_flags & PP_KEEPALIVE) ? 1 : 0; - return 0; - - case SERIAL_SETKEEPALIVE: - CP_DEBUG2 (d, ("ioctl: setkeepalive\n")); - /* Only for superuser! */ - error = priv_check (td, PRIV_DRIVER); - if (error) - return error; - if ((IFP2SP(d->ifp)->pp_flags & PP_FR) || - (d->ifp->if_flags & PP_CISCO)) - return EINVAL; - s = splimp (); - CP_LOCK (bd); - if (*(int*)data) - IFP2SP(d->ifp)->pp_flags |= PP_KEEPALIVE; - else - IFP2SP(d->ifp)->pp_flags &= ~PP_KEEPALIVE; - CP_UNLOCK (bd); - splx (s); - return 0; -#endif /*NETGRAPH*/ case SERIAL_GETMODE: CP_DEBUG2 (d, ("ioctl: getmode\n")); @@ -1308,18 +1027,7 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc error = priv_check (td, PRIV_DRIVER); if (error) return error; -#ifndef NETGRAPH - /* - * The debug_shadow is always greater than zero for logic - * simplicity. For switching debug off the IFF_DEBUG is - * responsible. - */ - d->chan->debug_shadow = (*(int*)data) ? (*(int*)data) : 1; - if (d->ifp->if_flags & IFF_DEBUG) - d->chan->debug = d->chan->debug_shadow; -#else d->chan->debug = *(int*)data; -#endif return 0; case SERIAL_GETHIGAIN: @@ -1783,7 +1491,6 @@ static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc return ENOTTY; } -#ifdef NETGRAPH static int ng_cp_constructor (node_p node) { drv_t *d = NG_NODE_PRIVATE (node); @@ -2209,7 +1916,6 @@ static int ng_cp_disconnect (hook_p hook) } return 0; } -#endif static int cp_modevent (module_t mod, int type, void *unused) { @@ -2217,10 +1923,8 @@ static int cp_modevent (module_t mod, int type, void *unused) switch (type) { case MOD_LOAD: -#ifdef NETGRAPH if (ng_newtype (&typestruct)) printf ("Failed to register ng_cp\n"); -#endif ++load_count; callout_init (&timeout_handle, 1); callout_reset (&timeout_handle, hz*5, cp_timeout, 0); @@ -2228,9 +1932,7 @@ static int cp_modevent (module_t mod, int type, void *unused) case MOD_UNLOAD: if (load_count == 1) { printf ("Removing device entry for Tau-PCI\n"); -#ifdef NETGRAPH ng_rmtype (&typestruct); -#endif } /* If we were wait it than it reasserted now, just stop it. * Actually we shouldn't get this condition. But code could be @@ -2246,7 +1948,6 @@ static int cp_modevent (module_t mod, int type, void *unused) return 0; } -#ifdef NETGRAPH static struct ng_type typestruct = { .version = NG_ABI_VERSION, .name = NG_CP_NODE_TYPE, @@ -2258,12 +1959,7 @@ static struct ng_type typestruct = { .rcvdata = ng_cp_rcvdata, .disconnect = ng_cp_disconnect, }; -#endif /*NETGRAPH*/ -#ifdef NETGRAPH MODULE_DEPEND (ng_cp, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION); -#else -MODULE_DEPEND (cp, sppp, 1, 1, 1); -#endif DRIVER_MODULE (cp, pci, cp_driver, cp_devclass, cp_modevent, NULL); MODULE_VERSION (cp, 1); diff --git a/sys/dev/cp/ng_cp.h b/sys/dev/cp/ng_cp.h index f35d81760499..f14461d4d683 100644 --- a/sys/dev/cp/ng_cp.h +++ b/sys/dev/cp/ng_cp.h @@ -16,8 +16,6 @@ * $FreeBSD$ */ -#ifdef NETGRAPH - #ifndef _CP_NETGRAPH_H_ #define _CP_NETGRAPH_H_ @@ -27,5 +25,3 @@ #define NG_CP_HOOK_DEBUG "debug" #endif /* _CP_NETGRAPH_H_ */ - -#endif /* NETGRAPH */ diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index 2f448c1d6063..a3434a90af77 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -490,12 +490,7 @@ device cpufreq # bxe: Broadcom NetXtreme II (BCM5771X/BCM578XX) PCIe 10Gb Ethernet # adapters. # ce: Cronyx Tau-PCI/32 sync single/dual port G.703/E1 serial adaptor -# with 32 HDLC subchannels (requires sppp (default), or NETGRAPH if -# NETGRAPH_CRONYX is configured) -# cp: Cronyx Tau-PCI sync single/dual/four port -# V.35/RS-232/RS-530/RS-449/X.21/G.703/E1/E3/T3/STS-1 -# serial adaptor (requires sppp (default), or NETGRAPH if -# NETGRAPH_CRONYX is configured) +# with 32 HDLC subchannels, requires NETGRAPH # igc: Intel I225 2.5G Ethernet adapter # ipw: Intel PRO/Wireless 2100 IEEE 802.11 adapter # iwi: Intel PRO/Wireless 2200BG/2225BG/2915ABG IEEE 802.11 adapters @@ -516,10 +511,8 @@ device cpufreq device bxe # Broadcom NetXtreme II BCM5771X/BCM578XX 10GbE device ce -device cp envvar hint.cs.0.at="isa" envvar hint.cs.0.port="0x300" -#options NETGRAPH_CRONYX # Enable NETGRAPH support for Cronyx adapter(s) options ED_3C503 options ED_HPP options ED_SIC diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 00f5bb281872..b253920b6dbe 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -353,7 +353,6 @@ SUBDIR= \ ${_speaker} \ spi \ ${_splash} \ - ${_sppp} \ ste \ stge \ ${_sume} \ @@ -665,7 +664,6 @@ _rdma= rdma _safe= safe _speaker= speaker _splash= splash -_sppp= sppp _p2sb= p2sb _wbwd= wbwd diff --git a/sys/modules/ce/Makefile b/sys/modules/ce/Makefile index e06340f29c2d..18f75f633f90 100644 --- a/sys/modules/ce/Makefile +++ b/sys/modules/ce/Makefile @@ -4,26 +4,7 @@ .PATH: ${SRCTOP}/sys/dev/ce KMOD = if_ce SRCS = if_ce.c ceddk.c tau32-ddk.c -SRCS += opt_bpf.h opt_netgraph.h opt_ng_cronyx.h device_if.h bus_if.h \ - pci_if.h - -.if !defined(KERNBUILDDIR) -PROTOS?= -DINET -NG_CRONYX?= 0 -NETGRAPH= ${NG_CRONYX} - -CFLAGS+= ${PROTOS} - -.if ${NETGRAPH} != 0 -opt_netgraph.h: - echo "#define NETGRAPH ${NETGRAPH}" > ${.TARGET} -.endif - -.if ${NG_CRONYX} != 0 -opt_ng_cronyx.h: - echo "#define NETGRAPH_CRONYX 1" > ${.TARGET} -.endif -.endif +SRCS += device_if.h bus_if.h pci_if.h .include diff --git a/sys/modules/cp/Makefile b/sys/modules/cp/Makefile index aaa505811459..3726651d3cc3 100644 --- a/sys/modules/cp/Makefile +++ b/sys/modules/cp/Makefile @@ -4,26 +4,7 @@ .PATH: ${SRCTOP}/sys/dev/cp KMOD = if_cp SRCS = if_cp.c cpddk.c -SRCS += opt_netgraph.h opt_ng_cronyx.h device_if.h bus_if.h \ - pci_if.h - -.if !defined(KERNBUILDDIR) -PROTOS?= -DINET -NG_CRONYX?= 0 -NETGRAPH= ${NG_CRONYX} - -CFLAGS+= ${PROTOS} - -.if ${NETGRAPH} != 0 -opt_netgraph.h: - echo "#define NETGRAPH ${NETGRAPH}" > ${.TARGET} -.endif - -.if ${NG_CRONYX} != 0 -opt_ng_cronyx.h: - echo "#define NETGRAPH_CRONYX 1" > ${.TARGET} -.endif -.endif +SRCS += device_if.h bus_if.h pci_if.h .include diff --git a/sys/modules/netgraph/Makefile b/sys/modules/netgraph/Makefile index 1c5da9a1692e..8054183d419b 100644 --- a/sys/modules/netgraph/Makefile +++ b/sys/modules/netgraph/Makefile @@ -47,7 +47,6 @@ SUBDIR= async \ socket \ source \ split \ - sppp \ tag \ tcpmss \ tee \ diff --git a/sys/modules/netgraph/sppp/Makefile b/sys/modules/netgraph/sppp/Makefile deleted file mode 100644 index 203e83e437ae..000000000000 --- a/sys/modules/netgraph/sppp/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# $FreeBSD$ -# Cronyx Id: ng_sppp.Makefile,v 1.1.2.1 2002/12/25 08:37:25 rik Exp $ - -KMOD= ng_sppp -SRCS= ng_sppp.c - -.include diff --git a/sys/modules/sppp/Makefile b/sys/modules/sppp/Makefile deleted file mode 100644 index 017940e6d4ad..000000000000 --- a/sys/modules/sppp/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/net - -KMOD= sppp -SRCS= if_spppfr.c if_spppsubr.c slcompress.c -SRCS+= opt_inet.h opt_inet6.h - -EXPORT_SYMS= sppp_attach \ - sppp_detach \ - sppp_input \ - sppp_ioctl \ - sppp_dequeue \ - sppp_pick \ - sppp_isempty \ - sppp_flush - -.include diff --git a/sys/net/if_sppp.h b/sys/net/if_sppp.h deleted file mode 100644 index 23a08e77669a..000000000000 --- a/sys/net/if_sppp.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Defines for synchronous PPP/Cisco/Frame Relay link level subroutines. - */ -/*- - * Copyright (C) 1994-2000 Cronyx Engineering. - * Author: Serge Vakulenko, - * - * Heavily revamped to conform to RFC 1661. - * Copyright (C) 1997, Joerg Wunsch. - * - * This software is distributed with NO WARRANTIES, not even the implied - * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Authors grant any other persons or organizations permission to use - * or modify this software as long as this message is kept with the software, - * all derivative works or modified versions. - * - * From: Version 2.0, Fri Oct 6 20:39:21 MSK 1995 - * - * $FreeBSD$ - */ - -#ifndef _NET_IF_SPPP_H_ -#define _NET_IF_SPPP_H_ 1 - -#define IDX_LCP 0 /* idx into state table */ - -struct slcp { - u_long opts; /* LCP options to send (bitfield) */ - u_long magic; /* local magic number */ - u_long mru; /* our max receive unit */ - u_long their_mru; /* their max receive unit */ - u_long protos; /* bitmask of protos that are started */ - u_char echoid; /* id of last keepalive echo request */ - /* restart max values, see RFC 1661 */ - int timeout; - int max_terminate; - int max_configure; - int max_failure; -}; - -#define IDX_IPCP 1 /* idx into state table */ -#define IDX_IPV6CP 2 /* idx into state table */ - -struct sipcp { - u_long opts; /* IPCP options to send (bitfield) */ - u_int flags; -#define IPCP_HISADDR_SEEN 1 /* have seen his address already */ -#define IPCP_MYADDR_DYN 2 /* my address is dynamically assigned */ -#define IPCP_MYADDR_SEEN 4 /* have seen his address already */ -#ifdef notdef -#define IPV6CP_MYIFID_DYN 8 /* my ifid is dynamically assigned */ -#endif -#define IPV6CP_MYIFID_SEEN 0x10 /* have seen his ifid already */ -#define IPCP_VJ 0x20 /* can use VJ compression */ - int max_state; /* VJ: Max-Slot-Id */ - int compress_cid; /* VJ: Comp-Slot-Id */ -}; - -#define AUTHNAMELEN 64 -#define AUTHKEYLEN 16 - -struct sauth { - u_short proto; /* authentication protocol to use */ - u_short flags; -#define AUTHFLAG_NOCALLOUT 1 /* do not require authentication on */ - /* callouts */ -#define AUTHFLAG_NORECHALLENGE 2 /* do not re-challenge CHAP */ - u_char name[AUTHNAMELEN]; /* system identification name */ - u_char secret[AUTHKEYLEN]; /* secret password */ - u_char challenge[AUTHKEYLEN]; /* random challenge */ -}; - -#define IDX_PAP 3 -#define IDX_CHAP 4 - -#define IDX_COUNT (IDX_CHAP + 1) /* bump this when adding cp's! */ - -/* - * Don't change the order of this. Ordering the phases this way allows - * for a comparison of ``pp_phase >= PHASE_AUTHENTICATE'' in order to - * know whether LCP is up. - */ -enum ppp_phase { - PHASE_DEAD, PHASE_ESTABLISH, PHASE_TERMINATE, - PHASE_AUTHENTICATE, PHASE_NETWORK -}; - -#define PP_MTU 1500 /* default/minimal MRU */ -#define PP_MAX_MRU 2048 /* maximal MRU we want to negotiate */ - -/* - * This is a cut down struct sppp (see below) that can easily be - * exported to/ imported from userland without the need to include - * dozens of kernel-internal header files. It is used by the - * SPPPIO[GS]DEFS ioctl commands below. - */ -struct sppp_parms { - enum ppp_phase pp_phase; /* phase we're currently in */ - int enable_vj; /* VJ header compression enabled */ - int enable_ipv6; /* - * Enable IPv6 negotiations -- only - * needed since each IPv4 i/f auto- - * matically gets an IPv6 address - * assigned, so we can't use this as - * a decision. - */ - struct slcp lcp; /* LCP params */ - struct sipcp ipcp; /* IPCP params */ - struct sipcp ipv6cp; /* IPv6CP params */ - struct sauth myauth; /* auth params, i'm peer */ - struct sauth hisauth; /* auth params, i'm authenticator */ -}; - -/* - * Definitions to pass struct sppp_parms data down into the kernel - * using the SIOC[SG]IFGENERIC ioctl interface. - * - * In order to use this, create a struct spppreq, fill in the cmd - * field with SPPPIOGDEFS, and put the address of this structure into - * the ifr_data portion of a struct ifreq. Pass this struct to a - * SIOCGIFGENERIC ioctl. Then replace the cmd field by SPPPIOSDEFS, - * modify the defs field as desired, and pass the struct ifreq now - * to a SIOCSIFGENERIC ioctl. - */ - -#define SPPPIOGDEFS ((caddr_t)(('S' << 24) + (1 << 16) +\ - sizeof(struct sppp_parms))) -#define SPPPIOSDEFS ((caddr_t)(('S' << 24) + (2 << 16) +\ - sizeof(struct sppp_parms))) - -struct spppreq { - int cmd; - struct sppp_parms defs; -}; - -#ifdef _KERNEL -struct sppp { - struct ifnet *pp_ifp; /* network interface data */ - struct ifqueue pp_fastq; /* fast output queue */ - struct ifqueue pp_cpq; /* PPP control protocol queue */ - struct sppp *pp_next; /* next interface in keepalive list */ - u_int pp_mode; /* major protocol modes (cisco/ppp/...) */ - u_int pp_flags; /* sub modes */ - u_short pp_alivecnt; /* keepalive packets counter */ - u_short pp_loopcnt; /* loopback detection counter */ - u_long pp_seq[IDX_COUNT]; /* local sequence number */ - u_long pp_rseq[IDX_COUNT]; /* remote sequence number */ - enum ppp_phase pp_phase; /* phase we're currently in */ - int state[IDX_COUNT]; /* state machine */ - u_char confid[IDX_COUNT]; /* id of last configuration request */ - int rst_counter[IDX_COUNT]; /* restart counter */ - int fail_counter[IDX_COUNT]; /* negotiation failure counter */ - int confflags; /* administrative configuration flags */ -#define CONF_ENABLE_VJ 0x01 /* VJ header compression enabled */ -#define CONF_ENABLE_IPV6 0x02 /* IPv6 administratively enabled */ - time_t pp_last_recv; /* time last packet has been received */ - time_t pp_last_sent; /* time last packet has been sent */ - struct callout ch[IDX_COUNT]; /* per-proto and if callouts */ - struct callout pap_my_to_ch; /* PAP needs one more... */ - struct callout keepalive_callout; /* keepalive callout */ - struct slcp lcp; /* LCP params */ - struct sipcp ipcp; /* IPCP params */ - struct sipcp ipv6cp; /* IPv6CP params */ - struct sauth myauth; /* auth params, i'm peer */ - struct sauth hisauth; /* auth params, i'm authenticator */ - struct slcompress *pp_comp; /* for VJ compression */ - u_short fr_dlci; /* Frame Relay DLCI number, 16..1023 */ - u_char fr_status; /* PVC status, active/new/delete */ - /* - * These functions are filled in by sppp_attach(), and are - * expected to be used by the lower layer (hardware) drivers - * in order to communicate the (un)availability of the - * communication link. Lower layer drivers that are always - * ready to communicate (like hardware HDLC) can shortcut - * pp_up from pp_tls, and pp_down from pp_tlf. - */ - void (*pp_up)(struct sppp *sp); - void (*pp_down)(struct sppp *sp); - /* - * These functions need to be filled in by the lower layer - * (hardware) drivers if they request notification from the - * PPP layer whether the link is actually required. They - * correspond to the tls and tlf actions. - */ - void (*pp_tls)(struct sppp *sp); - void (*pp_tlf)(struct sppp *sp); - /* - * These (optional) functions may be filled by the hardware - * driver if any notification of established connections - * (currently: IPCP up) is desired (pp_con) or any internal - * state change of the interface state machine should be - * signaled for monitoring purposes (pp_chg). - */ - void (*pp_con)(struct sppp *sp); - void (*pp_chg)(struct sppp *sp, int new_state); - /* These two fields are for use by the lower layer */ - void *pp_lowerp; - int pp_loweri; - /* Lock */ - struct mtx mtx; - /* if_start () wrapper */ - void (*if_start) (struct ifnet *); - struct callout ifstart_callout; /* if_start () scheduler */ -}; -#define IFP2SP(ifp) ((struct sppp *)(ifp)->if_l2com) -#define SP2IFP(sp) ((sp)->pp_ifp) - -/* bits for pp_flags */ -#define PP_KEEPALIVE 0x01 /* use keepalive protocol */ -#define PP_FR 0x04 /* use Frame Relay protocol instead of PPP */ - /* 0x04 was PP_TIMO */ -#define PP_CALLIN 0x08 /* we are being called */ -#define PP_NEEDAUTH 0x10 /* remote requested authentication */ - -void sppp_attach (struct ifnet *ifp); -void sppp_detach (struct ifnet *ifp); -void sppp_input (struct ifnet *ifp, struct mbuf *m); -int sppp_ioctl (struct ifnet *ifp, u_long cmd, void *data); -struct mbuf *sppp_dequeue (struct ifnet *ifp); -struct mbuf *sppp_pick(struct ifnet *ifp); -int sppp_isempty (struct ifnet *ifp); -void sppp_flush (struct ifnet *ifp); - -/* Internal functions */ -void sppp_fr_input (struct sppp *sp, struct mbuf *m); -struct mbuf *sppp_fr_header (struct sppp *sp, struct mbuf *m, int fam); -void sppp_fr_keepalive (struct sppp *sp); -void sppp_get_ip_addrs(struct sppp *sp, u_long *src, u_long *dst, - u_long *srcmask); - -#endif - -#endif /* _NET_IF_SPPP_H_ */ diff --git a/sys/net/if_spppfr.c b/sys/net/if_spppfr.c deleted file mode 100644 index d84cc46c7cb6..000000000000 --- a/sys/net/if_spppfr.c +++ /dev/null @@ -1,611 +0,0 @@ -/*- - * Synchronous Frame Relay link level subroutines. - * ANSI T1.617-compaible link management signaling - * implemented for Frame Relay mode. - * Cisco-type Frame Relay framing added, thanks Alex Tutubalin. - * Only one DLCI per channel for now. - * - * Copyright (C) 1994-2000 Cronyx Engineering. - * Author: Serge Vakulenko, - * - * Copyright (C) 1999-2004 Cronyx Engineering. - * Author: Kurakin Roman, - * - * This software is distributed with NO WARRANTIES, not even the implied - * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Authors grant any other persons or organisations a permission to use, - * modify and redistribute this software in source and binary forms, - * as long as this message is kept with the software, all derivative - * works or modified versions. - * - * $Cronyx Id: if_spppfr.c,v 1.1.2.10 2004/06/29 09:02:30 rik Exp $ - * $FreeBSD$ - */ - -#include - -#if defined(__FreeBSD__) -#include "opt_inet.h" -#include "opt_inet6.h" -#endif - -#ifdef NetBSD1_3 -# if NetBSD1_3 > 6 -# include "opt_inet.h" -# include "opt_inet6.h" -# include "opt_iso.h" -# endif -#endif - -#include -#include -#include -#include -#include -#include -#if defined(__FreeBSD__) -#include -#endif -#include -#include - -#if defined (__OpenBSD__) -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined (__NetBSD__) || defined (__OpenBSD__) -#include /* XXX for softnet */ -#endif - -#include - -#include -#ifdef INET -#include -#include -#endif - -#if defined (__FreeBSD__) || defined (__OpenBSD__) -# include -#else -# include -#endif - -#include - -/* - * Frame Relay. - */ -#define FR_UI 0x03 /* Unnumbered Information */ -#define FR_IP 0xCC /* IP protocol identifier */ -#define FR_PADDING 0x00 /* NLPID padding */ -#define FR_SIGNALING 0x08 /* Q.933/T1.617 signaling identifier */ -#define FR_SNAP 0x80 /* NLPID snap */ - -/* - * Header flags. - */ -#define FR_DE 0x02 /* discard eligibility */ -#define FR_FECN 0x04 /* forward notification */ -#define FR_BECN 0x08 /* backward notification */ - -/* - * Signaling message types. - */ -#define FR_MSG_ENQUIRY 0x75 /* status enquiry */ -#define FR_MSG_STATUS 0x7d /* status */ - -#define FR_ENQUIRY_SIZE 14 - -/* - * Message field types. - */ -#define FR_FLD_RTYPE 0x01 /* report type */ -#define FR_FLD_VERIFY 0x03 /* link verification */ -#define FR_FLD_PVC 0x07 /* PVC status */ -#define FR_FLD_LSHIFT5 0x95 /* locking shift 5 */ - -/* - * Report types. - */ -#define FR_RTYPE_FULL 0 /* full status */ -#define FR_RTYPE_SHORT 1 /* link verification only */ -#define FR_RTYPE_SINGLE 2 /* single PVC status */ - -/* PVC status field. */ -#define FR_DLCI_DELETE 0x04 /* PVC is deleted */ -#define FR_DLCI_ACTIVE 0x02 /* PVC is operational */ -#define FR_DLCI_NEW 0x08 /* PVC is new */ - -struct arp_req { - unsigned short htype; /* hardware type = ARPHRD_FRELAY */ - unsigned short ptype; /* protocol type = ETHERTYPE_IP */ - unsigned char halen; /* hardware address length = 2 */ - unsigned char palen; /* protocol address length = 4 */ - unsigned short op; /* ARP/RARP/InARP request/reply */ - unsigned short hsource; /* hardware source address */ - unsigned short psource1; /* protocol source */ - unsigned short psource2; - unsigned short htarget; /* hardware target address */ - unsigned short ptarget1; /* protocol target */ - unsigned short ptarget2; -} __packed; - -#if defined(__FreeBSD__) && __FreeBSD_version < 501113 -#define SPP_FMT "%s%d: " -#define SPP_ARGS(ifp) (ifp)->if_name, (ifp)->if_unit -#else -#define SPP_FMT "%s: " -#define SPP_ARGS(ifp) (ifp)->if_xname -#endif - -/* almost every function needs these */ -#define STDDCL \ - struct ifnet *ifp = SP2IFP(sp); \ - int debug = ifp->if_flags & IFF_DEBUG - -static void sppp_fr_arp (struct sppp *sp, struct arp_req *req, u_short addr); -static void sppp_fr_signal (struct sppp *sp, unsigned char *h, int len); - -void sppp_fr_input (struct sppp *sp, struct mbuf *m) -{ - STDDCL; - u_char *h = mtod (m, u_char*); - int isr = -1; - int dlci, hlen, proto; - - /* Get the DLCI number. */ - if (m->m_pkthdr.len < 10) { -bad: m_freem (m); - return; - } - dlci = (h[0] << 2 & 0x3f0) | (h[1] >> 4 & 0x0f); - - /* Process signaling packets. */ - if (dlci == 0) { - sppp_fr_signal (sp, h, m->m_pkthdr.len); - m_freem (m); - return; - } - - if (dlci != sp->fr_dlci) { - if (debug) - printf (SPP_FMT "Received packet from invalid DLCI %d\n", - SPP_ARGS(ifp), dlci); - goto bad; - } - - /* Process the packet. */ - if (ntohs (*(short*) (h+2)) == ETHERTYPE_IP) { - /* Prehistoric IP framing? */ - h[2] = FR_UI; - h[3] = FR_IP; - } - if (h[2] != FR_UI) { - if (debug) - printf (SPP_FMT "Invalid frame relay header flag 0x%02x\n", - SPP_ARGS(ifp), h[2]); - goto bad; - } - switch (h[3]) { - default: - if (debug) - printf (SPP_FMT "Unsupported NLPID 0x%02x\n", - SPP_ARGS(ifp), h[3]); - goto bad; - - case FR_PADDING: - if (h[4] != FR_SNAP) { - if (debug) - printf (SPP_FMT "Bad NLPID 0x%02x\n", - SPP_ARGS(ifp), h[4]); - goto bad; - } - if (h[5] || h[6] || h[7]) { - if (debug) - printf (SPP_FMT "Bad OID 0x%02x-0x%02x-0x%02x\n", - SPP_ARGS(ifp), - h[5], h[6], h[7]); - goto bad; - } - proto = ntohs (*(short*) (h+8)); - if (proto == ETHERTYPE_ARP) { - /* Process the ARP request. */ - if (m->m_pkthdr.len != 10 + sizeof (struct arp_req)) { - if (debug) - printf (SPP_FMT "Bad ARP request size = %d bytes\n", - SPP_ARGS(ifp), - m->m_pkthdr.len); - goto bad; - } - sppp_fr_arp (sp, (struct arp_req*) (h + 10), - h[0] << 8 | h[1]); - m_freem (m); - return; - } - hlen = 10; - break; - - case FR_IP: - proto = ETHERTYPE_IP; - hlen = 4; - break; - } - - /* Remove frame relay header. */ - m_adj (m, hlen); - - switch (proto) { - default: - if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1); -drop: if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); - m_freem (m); - return; -#ifdef INET - case ETHERTYPE_IP: - isr = NETISR_IP; - break; -#endif - } - - if (! (ifp->if_flags & IFF_UP)) - goto drop; - - M_SETFIB(m, ifp->if_fib); - - /* Check queue. */ - if (netisr_queue(isr, m)) { /* (0) on success. */ - if (debug) - log(LOG_DEBUG, SPP_FMT "protocol queue overflow\n", - SPP_ARGS(ifp)); - } -} - -/* - * Add the frame relay header to the packet. - * For IP the header length is 4 bytes, - * for all other protocols - 10 bytes (RFC 1490). - */ -struct mbuf *sppp_fr_header (struct sppp *sp, struct mbuf *m, - int family) -{ - STDDCL; - u_char *h; - int type, hlen; - - /* Prepend the space for Frame Relay header. */ - hlen = (family == AF_INET) ? 4 : 10; - M_PREPEND (m, hlen, M_NOWAIT); - if (! m) - return 0; - h = mtod (m, u_char*); - - /* Fill the header. */ - h[0] = sp->fr_dlci >> 2 & 0xfc; - h[1] = sp->fr_dlci << 4 | 1; - h[2] = FR_UI; - - switch (family) { - default: - if (debug) - printf (SPP_FMT "Cannot handle address family %d\n", - SPP_ARGS(ifp), family); - m_freem (m); - return 0; -#ifdef INET - case AF_INET: -#if 0 /* Crashes on fragmented packets */ - /* - * Set the discard eligibility bit, if: - * 1) no fragmentation - * 2) length > 400 bytes - * 3a) the protocol is UDP or - * 3b) TCP data (no control bits) - */ - { - struct ip *ip = (struct ip*) (h + hlen); - struct tcphdr *tcp = (struct tcphdr*) ((long*)ip + ip->ip_hl); - - if (! (ip->ip_off & ~IP_DF) && ip->ip_len > 400 && - (ip->ip_p == IPPROTO_UDP || - ip->ip_p == IPPROTO_TCP && ! tcp->th_flags)) - h[1] |= FR_DE; - } -#endif - h[3] = FR_IP; - return m; -#endif -#ifdef NS - case AF_NS: - type = 0x8137; - break; -#endif - } - h[3] = FR_PADDING; - h[4] = FR_SNAP; - h[5] = 0; - h[6] = 0; - h[7] = 0; - *(short*) (h+8) = htons(type); - return m; -} - -/* - * Send periodical frame relay link verification messages via DLCI 0. - * Called every 10 seconds (default value of T391 timer is 10 sec). - * Every 6-th message is a full status request - * (default value of N391 counter is 6). - */ -void sppp_fr_keepalive (struct sppp *sp) -{ - STDDCL; - unsigned char *h, *p; - struct mbuf *m; - - MGETHDR (m, M_NOWAIT, MT_DATA); - if (! m) - return; - m->m_pkthdr.rcvif = 0; - - h = mtod (m, u_char*); - p = h; - *p++ = 0; /* DLCI = 0 */ - *p++ = 1; - *p++ = FR_UI; - *p++ = FR_SIGNALING; /* NLPID = UNI call control */ - - *p++ = 0; /* call reference length = 0 */ - *p++ = FR_MSG_ENQUIRY; /* message type = status enquiry */ - - *p++ = FR_FLD_LSHIFT5; /* locking shift 5 */ - - *p++ = FR_FLD_RTYPE; /* report type field */ - *p++ = 1; /* report type length = 1 */ - if (sp->pp_seq[IDX_LCP] % 6) - *p++ = FR_RTYPE_SHORT; /* link verification only */ - else - *p++ = FR_RTYPE_FULL; /* full status needed */ - - if (sp->pp_seq[IDX_LCP] >= 255) - sp->pp_seq[IDX_LCP] = 0; - *p++ = FR_FLD_VERIFY; /* link verification type field */ - *p++ = 2; /* link verification field length = 2 */ - *p++ = ++sp->pp_seq[IDX_LCP]; /* our sequence number */ - *p++ = sp->pp_rseq[IDX_LCP]; /* last received sequence number */ - - m->m_pkthdr.len = m->m_len = p - h; - if (debug) - printf (SPP_FMT "send lmi packet, seq=%d, rseq=%d\n", - SPP_ARGS(ifp), (u_char) sp->pp_seq[IDX_LCP], - (u_char) sp->pp_rseq[IDX_LCP]); - - if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3)) - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); -} - -/* - * Process the frame relay Inverse ARP request. - */ -static void sppp_fr_arp (struct sppp *sp, struct arp_req *req, - u_short his_hardware_address) -{ - STDDCL; - struct mbuf *m; - struct arp_req *reply; - u_char *h; - u_short my_hardware_address; - u_long his_ip_address, my_ip_address; - - if ((ntohs (req->htype) != ARPHRD_FRELAY || - ntohs (req->htype) != 16) || /* for BayNetworks routers */ - ntohs (req->ptype) != ETHERTYPE_IP) { - if (debug) - printf (SPP_FMT "Invalid ARP hardware/protocol type = 0x%x/0x%x\n", - SPP_ARGS(ifp), - ntohs (req->htype), ntohs (req->ptype)); - return; - } - if (req->halen != 2 || req->palen != 4) { - if (debug) - printf (SPP_FMT "Invalid ARP hardware/protocol address length = %d/%d\n", - SPP_ARGS(ifp), - req->halen, req->palen); - return; - } - switch (ntohs (req->op)) { - default: - if (debug) - printf (SPP_FMT "Invalid ARP op = 0x%x\n", - SPP_ARGS(ifp), ntohs (req->op)); - return; - - case ARPOP_INVREPLY: - /* Ignore. */ - return; - - case ARPOP_INVREQUEST: - my_hardware_address = ntohs (req->htarget); - his_ip_address = ntohs (req->psource1) << 16 | - ntohs (req->psource2); - my_ip_address = ntohs (req->ptarget1) << 16 | - ntohs (req->ptarget2); - break; - } - if (debug) - printf (SPP_FMT "got ARP request, source=0x%04x/%d.%d.%d.%d, target=0x%04x/%d.%d.%d.%d\n", - SPP_ARGS(ifp), ntohs (req->hsource), - (unsigned char) (his_ip_address >> 24), - (unsigned char) (his_ip_address >> 16), - (unsigned char) (his_ip_address >> 8), - (unsigned char) his_ip_address, - my_hardware_address, - (unsigned char) (my_ip_address >> 24), - (unsigned char) (my_ip_address >> 16), - (unsigned char) (my_ip_address >> 8), - (unsigned char) my_ip_address); - - sppp_get_ip_addrs (sp, &my_ip_address, 0, 0); - if (! my_ip_address) - return; /* nothing to reply */ - - if (debug) - printf (SPP_FMT "send ARP reply, source=0x%04x/%d.%d.%d.%d, target=0x%04x/%d.%d.%d.%d\n", - SPP_ARGS(ifp), my_hardware_address, - (unsigned char) (my_ip_address >> 24), - (unsigned char) (my_ip_address >> 16), - (unsigned char) (my_ip_address >> 8), - (unsigned char) my_ip_address, - his_hardware_address, - (unsigned char) (his_ip_address >> 24), - (unsigned char) (his_ip_address >> 16), - (unsigned char) (his_ip_address >> 8), - (unsigned char) his_ip_address); - - /* Send the Inverse ARP reply. */ - MGETHDR (m, M_NOWAIT, MT_DATA); - if (! m) - return; - m->m_pkthdr.len = m->m_len = 10 + sizeof (*reply); - m->m_pkthdr.rcvif = 0; - - h = mtod (m, u_char*); - reply = (struct arp_req*) (h + 10); - - h[0] = his_hardware_address >> 8; - h[1] = his_hardware_address; - h[2] = FR_UI; - h[3] = FR_PADDING; - h[4] = FR_SNAP; - h[5] = 0; - h[6] = 0; - h[7] = 0; - *(short*) (h+8) = htons (ETHERTYPE_ARP); - - reply->htype = htons (ARPHRD_FRELAY); - reply->ptype = htons (ETHERTYPE_IP); - reply->halen = 2; - reply->palen = 4; - reply->op = htons (ARPOP_INVREPLY); - reply->hsource = htons (my_hardware_address); - reply->psource1 = htonl (my_ip_address); - reply->psource2 = htonl (my_ip_address) >> 16; - reply->htarget = htons (his_hardware_address); - reply->ptarget1 = htonl (his_ip_address); - reply->ptarget2 = htonl (his_ip_address) >> 16; - - if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3)) - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); -} - -/* - * Process the input signaling packet (DLCI 0). - * The implemented protocol is ANSI T1.617 Annex D. - */ -static void sppp_fr_signal (struct sppp *sp, unsigned char *h, int len) -{ - STDDCL; - u_char *p; - int dlci; - - if (h[2] != FR_UI || h[3] != FR_SIGNALING || h[4] != 0) { - if (debug) - printf (SPP_FMT "Invalid signaling header\n", - SPP_ARGS(ifp)); -bad: if (debug) { - printf ("%02x", *h++); - while (--len > 0) - printf ("-%02x", *h++); - printf ("\n"); - } - return; - } - if (h[5] == FR_MSG_ENQUIRY) { - if (len == FR_ENQUIRY_SIZE && - h[12] == (u_char) sp->pp_seq[IDX_LCP]) { - sp->pp_seq[IDX_LCP] = random(); - printf (SPP_FMT "loopback detected\n", - SPP_ARGS(ifp)); - } - return; - } - if (h[5] != FR_MSG_STATUS) { - if (debug) - printf (SPP_FMT "Unknown signaling message: 0x%02x\n", - SPP_ARGS(ifp), h[5]); - goto bad; - } - - /* Parse message fields. */ - for (p=h+6; ppp_rseq[IDX_LCP] = p[2]; - if (debug) { - printf (SPP_FMT "got lmi reply rseq=%d, seq=%d", - SPP_ARGS(ifp), p[2], p[3]); - if (p[3] != (u_char) sp->pp_seq[IDX_LCP]) - printf (" (really %d)", - (u_char) sp->pp_seq[IDX_LCP]); - printf ("\n"); - } - break; - case FR_FLD_PVC: - if (p[1] < 3) { - if (debug) - printf (SPP_FMT "Invalid PVC status length %d\n", - SPP_ARGS(ifp), p[1]); - break; - } - dlci = (p[2] << 4 & 0x3f0) | (p[3] >> 3 & 0x0f); - if (! sp->fr_dlci) - sp->fr_dlci = dlci; - if (sp->fr_status != p[4]) - printf (SPP_FMT "DLCI %d %s%s\n", - SPP_ARGS(ifp), dlci, - p[4] & FR_DLCI_DELETE ? "deleted" : - p[4] & FR_DLCI_ACTIVE ? "active" : "passive", - p[4] & FR_DLCI_NEW ? ", new" : ""); - sp->fr_status = p[4]; - break; - } - if (*p & 0x80) - ++p; - else if (p < h+len+1 && p[1]) - p += 2 + p[1]; - else { - if (debug) - printf (SPP_FMT "Invalid signaling field 0x%x\n", - SPP_ARGS(ifp), *p); - goto bad; - } - } -} diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c deleted file mode 100644 index 804367025532..000000000000 --- a/sys/net/if_spppsubr.c +++ /dev/null @@ -1,5418 +0,0 @@ -/* - * Synchronous PPP/Cisco/Frame Relay link level subroutines. - * Keepalive protocol implemented in both Cisco and PPP modes. - */ -/*- - * Copyright (C) 1994-2000 Cronyx Engineering. - * Author: Serge Vakulenko, - * - * Heavily revamped to conform to RFC 1661. - * Copyright (C) 1997, 2001 Joerg Wunsch. - * - * This software is distributed with NO WARRANTIES, not even the implied - * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Authors grant any other persons or organisations permission to use - * or modify this software as long as this message is kept with the software, - * all derivative works or modified versions. - * - * From: Version 2.4, Thu Apr 30 17:17:21 MSD 1997 - * - * $FreeBSD$ - */ - -#include - -#include "opt_inet.h" -#include "opt_inet6.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#ifdef INET -#include -#include -#endif - -#ifdef INET6 -#include -#endif - -#include - -#include - -#define IOCTL_CMD_T u_long -#define MAXALIVECNT 3 /* max. alive packets */ - -/* - * Interface flags that can be set in an ifconfig command. - * - * Setting link0 will make the link passive, i.e. it will be marked - * as being administrative openable, but won't be opened to begin - * with. Incoming calls will be answered, or subsequent calls with - * -link1 will cause the administrative open of the LCP layer. - * - * Setting link1 will cause the link to auto-dial only as packets - * arrive to be sent. - * - * Setting IFF_DEBUG will syslog the option negotiation and state - * transitions at level kern.debug. Note: all logs consistently look - * like - * - * : - * - * with being something like "bppp0", and - * being one of "lcp", "ipcp", "cisco", "chap", "pap", etc. - */ - -#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ -#define IFF_AUTO IFF_LINK1 /* auto-dial on output */ -#define IFF_CISCO IFF_LINK2 /* auto-dial on output */ - -#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ -#define PPP_UI 0x03 /* Unnumbered Information */ -#define PPP_IP 0x0021 /* Internet Protocol */ -#define PPP_ISO 0x0023 /* ISO OSI Protocol */ -#define PPP_XNS 0x0025 /* Xerox NS Protocol */ -#define PPP_IPX 0x002b /* Novell IPX Protocol */ -#define PPP_VJ_COMP 0x002d /* VJ compressed TCP/IP */ -#define PPP_VJ_UCOMP 0x002f /* VJ uncompressed TCP/IP */ -#define PPP_IPV6 0x0057 /* Internet Protocol Version 6 */ -#define PPP_LCP 0xc021 /* Link Control Protocol */ -#define PPP_PAP 0xc023 /* Password Authentication Protocol */ -#define PPP_CHAP 0xc223 /* Challenge-Handshake Auth Protocol */ -#define PPP_IPCP 0x8021 /* Internet Protocol Control Protocol */ -#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ - -#define CONF_REQ 1 /* PPP configure request */ -#define CONF_ACK 2 /* PPP configure acknowledge */ -#define CONF_NAK 3 /* PPP configure negative ack */ -#define CONF_REJ 4 /* PPP configure reject */ -#define TERM_REQ 5 /* PPP terminate request */ -#define TERM_ACK 6 /* PPP terminate acknowledge */ -#define CODE_REJ 7 /* PPP code reject */ -#define PROTO_REJ 8 /* PPP protocol reject */ -#define ECHO_REQ 9 /* PPP echo request */ -#define ECHO_REPLY 10 /* PPP echo reply */ -#define DISC_REQ 11 /* PPP discard request */ - -#define LCP_OPT_MRU 1 /* maximum receive unit */ -#define LCP_OPT_ASYNC_MAP 2 /* async control character map */ -#define LCP_OPT_AUTH_PROTO 3 /* authentication protocol */ -#define LCP_OPT_QUAL_PROTO 4 /* quality protocol */ -#define LCP_OPT_MAGIC 5 /* magic number */ -#define LCP_OPT_RESERVED 6 /* reserved */ -#define LCP_OPT_PROTO_COMP 7 /* protocol field compression */ -#define LCP_OPT_ADDR_COMP 8 /* address/control field compression */ - -#define IPCP_OPT_ADDRESSES 1 /* both IP addresses; deprecated */ -#define IPCP_OPT_COMPRESSION 2 /* IP compression protocol (VJ) */ -#define IPCP_OPT_ADDRESS 3 /* local IP address */ - -#define IPV6CP_OPT_IFID 1 /* interface identifier */ -#define IPV6CP_OPT_COMPRESSION 2 /* IPv6 compression protocol */ - -#define IPCP_COMP_VJ 0x2d /* Code for VJ compression */ - -#define PAP_REQ 1 /* PAP name/password request */ -#define PAP_ACK 2 /* PAP acknowledge */ -#define PAP_NAK 3 /* PAP fail */ - -#define CHAP_CHALLENGE 1 /* CHAP challenge request */ -#define CHAP_RESPONSE 2 /* CHAP challenge response */ -#define CHAP_SUCCESS 3 /* CHAP response ok */ -#define CHAP_FAILURE 4 /* CHAP response failed */ - -#define CHAP_MD5 5 /* hash algorithm - MD5 */ - -#define CISCO_MULTICAST 0x8f /* Cisco multicast address */ -#define CISCO_UNICAST 0x0f /* Cisco unicast address */ -#define CISCO_KEEPALIVE 0x8035 /* Cisco keepalive protocol */ -#define CISCO_ADDR_REQ 0 /* Cisco address request */ -#define CISCO_ADDR_REPLY 1 /* Cisco address reply */ -#define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */ - -/* states are named and numbered according to RFC 1661 */ -#define STATE_INITIAL 0 -#define STATE_STARTING 1 -#define STATE_CLOSED 2 -#define STATE_STOPPED 3 -#define STATE_CLOSING 4 -#define STATE_STOPPING 5 -#define STATE_REQ_SENT 6 -#define STATE_ACK_RCVD 7 -#define STATE_ACK_SENT 8 -#define STATE_OPENED 9 - -static MALLOC_DEFINE(M_SPPP, "sppp", "synchronous PPP interface internals"); - -struct ppp_header { - u_char address; - u_char control; - u_short protocol; -} __packed; -#define PPP_HEADER_LEN sizeof (struct ppp_header) - -struct lcp_header { - u_char type; - u_char ident; - u_short len; -} __packed; -#define LCP_HEADER_LEN sizeof (struct lcp_header) - -struct cisco_packet { - u_long type; - u_long par1; - u_long par2; - u_short rel; - u_short time0; - u_short time1; -} __packed; -#define CISCO_PACKET_LEN sizeof (struct cisco_packet) - -/* - * We follow the spelling and capitalization of RFC 1661 here, to make - * it easier comparing with the standard. Please refer to this RFC in - * case you can't make sense out of these abbreviation; it will also - * explain the semantics related to the various events and actions. - */ -struct cp { - u_short proto; /* PPP control protocol number */ - u_char protoidx; /* index into state table in struct sppp */ - u_char flags; -#define CP_LCP 0x01 /* this is the LCP */ -#define CP_AUTH 0x02 /* this is an authentication protocol */ -#define CP_NCP 0x04 /* this is a NCP */ -#define CP_QUAL 0x08 /* this is a quality reporting protocol */ - const char *name; /* name of this control protocol */ - /* event handlers */ - void (*Up)(struct sppp *sp); - void (*Down)(struct sppp *sp); - void (*Open)(struct sppp *sp); - void (*Close)(struct sppp *sp); - void (*TO)(void *sp); - int (*RCR)(struct sppp *sp, struct lcp_header *h, int len); - void (*RCN_rej)(struct sppp *sp, struct lcp_header *h, int len); - void (*RCN_nak)(struct sppp *sp, struct lcp_header *h, int len); - /* actions */ - void (*tlu)(struct sppp *sp); - void (*tld)(struct sppp *sp); - void (*tls)(struct sppp *sp); - void (*tlf)(struct sppp *sp); - void (*scr)(struct sppp *sp); -}; - -#define SPP_FMT "%s: " -#define SPP_ARGS(ifp) (ifp)->if_xname - -#define SPPP_LOCK(sp) mtx_lock (&(sp)->mtx) -#define SPPP_UNLOCK(sp) mtx_unlock (&(sp)->mtx) -#define SPPP_LOCK_ASSERT(sp) mtx_assert (&(sp)->mtx, MA_OWNED) -#define SPPP_LOCK_OWNED(sp) mtx_owned (&(sp)->mtx) - -#ifdef INET -/* - * The following disgusting hack gets around the problem that IP TOS - * can't be set yet. We want to put "interactive" traffic on a high - * priority queue. To decide if traffic is interactive, we check that - * a) it is TCP and b) one of its ports is telnet, rlogin or ftp control. - * - * XXX is this really still necessary? - joerg - - */ -static const u_short interactive_ports[8] = { - 0, 513, 0, 0, - 0, 21, 0, 23, -}; -#define INTERACTIVE(p) (interactive_ports[(p) & 7] == (p)) -#endif - -/* almost every function needs these */ -#define STDDCL \ - struct ifnet *ifp = SP2IFP(sp); \ - int debug = ifp->if_flags & IFF_DEBUG - -static int sppp_output(struct ifnet *ifp, struct mbuf *m, - const struct sockaddr *dst, struct route *ro); - -static void sppp_cisco_send(struct sppp *sp, int type, long par1, long par2); -static void sppp_cisco_input(struct sppp *sp, struct mbuf *m); - -static void sppp_cp_input(const struct cp *cp, struct sppp *sp, - struct mbuf *m); -static void sppp_cp_send(struct sppp *sp, u_short proto, u_char type, - u_char ident, u_short len, void *data); -/* static void sppp_cp_timeout(void *arg); */ -static void sppp_cp_change_state(const struct cp *cp, struct sppp *sp, - int newstate); -static void sppp_auth_send(const struct cp *cp, - struct sppp *sp, unsigned int type, unsigned int id, - ...); - -static void sppp_up_event(const struct cp *cp, struct sppp *sp); -static void sppp_down_event(const struct cp *cp, struct sppp *sp); -static void sppp_open_event(const struct cp *cp, struct sppp *sp); -static void sppp_close_event(const struct cp *cp, struct sppp *sp); -static void sppp_to_event(const struct cp *cp, struct sppp *sp); - -static void sppp_null(struct sppp *sp); - -static void sppp_pp_up(struct sppp *sp); -static void sppp_pp_down(struct sppp *sp); - -static void sppp_lcp_init(struct sppp *sp); -static void sppp_lcp_up(struct sppp *sp); -static void sppp_lcp_down(struct sppp *sp); -static void sppp_lcp_open(struct sppp *sp); -static void sppp_lcp_close(struct sppp *sp); -static void sppp_lcp_TO(void *sp); -static int sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len); -static void sppp_lcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len); -static void sppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len); -static void sppp_lcp_tlu(struct sppp *sp); -static void sppp_lcp_tld(struct sppp *sp); -static void sppp_lcp_tls(struct sppp *sp); -static void sppp_lcp_tlf(struct sppp *sp); -static void sppp_lcp_scr(struct sppp *sp); -static void sppp_lcp_check_and_close(struct sppp *sp); -static int sppp_ncp_check(struct sppp *sp); - -static void sppp_ipcp_init(struct sppp *sp); -static void sppp_ipcp_up(struct sppp *sp); -static void sppp_ipcp_down(struct sppp *sp); -static void sppp_ipcp_open(struct sppp *sp); -static void sppp_ipcp_close(struct sppp *sp); -static void sppp_ipcp_TO(void *sp); -static int sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len); -static void sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len); -static void sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len); -static void sppp_ipcp_tlu(struct sppp *sp); -static void sppp_ipcp_tld(struct sppp *sp); -static void sppp_ipcp_tls(struct sppp *sp); -static void sppp_ipcp_tlf(struct sppp *sp); -static void sppp_ipcp_scr(struct sppp *sp); - -static void sppp_ipv6cp_init(struct sppp *sp); -static void sppp_ipv6cp_up(struct sppp *sp); -static void sppp_ipv6cp_down(struct sppp *sp); -static void sppp_ipv6cp_open(struct sppp *sp); -static void sppp_ipv6cp_close(struct sppp *sp); -static void sppp_ipv6cp_TO(void *sp); -static int sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len); -static void sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len); -static void sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len); -static void sppp_ipv6cp_tlu(struct sppp *sp); -static void sppp_ipv6cp_tld(struct sppp *sp); -static void sppp_ipv6cp_tls(struct sppp *sp); -static void sppp_ipv6cp_tlf(struct sppp *sp); -static void sppp_ipv6cp_scr(struct sppp *sp); - -static void sppp_pap_input(struct sppp *sp, struct mbuf *m); -static void sppp_pap_init(struct sppp *sp); -static void sppp_pap_open(struct sppp *sp); -static void sppp_pap_close(struct sppp *sp); -static void sppp_pap_TO(void *sp); -static void sppp_pap_my_TO(void *sp); -static void sppp_pap_tlu(struct sppp *sp); -static void sppp_pap_tld(struct sppp *sp); -static void sppp_pap_scr(struct sppp *sp); - -static void sppp_chap_input(struct sppp *sp, struct mbuf *m); -static void sppp_chap_init(struct sppp *sp); -static void sppp_chap_open(struct sppp *sp); -static void sppp_chap_close(struct sppp *sp); -static void sppp_chap_TO(void *sp); -static void sppp_chap_tlu(struct sppp *sp); -static void sppp_chap_tld(struct sppp *sp); -static void sppp_chap_scr(struct sppp *sp); - -static const char *sppp_auth_type_name(u_short proto, u_char type); -static const char *sppp_cp_type_name(u_char type); -#ifdef INET -static const char *sppp_dotted_quad(u_long addr); -static const char *sppp_ipcp_opt_name(u_char opt); -#endif -#ifdef INET6 -static const char *sppp_ipv6cp_opt_name(u_char opt); -#endif -static const char *sppp_lcp_opt_name(u_char opt); -static const char *sppp_phase_name(enum ppp_phase phase); -static const char *sppp_proto_name(u_short proto); -static const char *sppp_state_name(int state); -static int sppp_params(struct sppp *sp, u_long cmd, void *data); -static int sppp_strnlen(u_char *p, int max); -static void sppp_keepalive(void *dummy); -static void sppp_phase_network(struct sppp *sp); -static void sppp_print_bytes(const u_char *p, u_short len); -static void sppp_print_string(const char *p, u_short len); -static void sppp_qflush(struct ifqueue *ifq); -#ifdef INET -static void sppp_set_ip_addr(struct sppp *sp, u_long src); -#endif -#ifdef INET6 -static void sppp_get_ip6_addrs(struct sppp *sp, struct in6_addr *src, - struct in6_addr *dst, struct in6_addr *srcmask); -#ifdef IPV6CP_MYIFID_DYN -static void sppp_set_ip6_addr(struct sppp *sp, const struct in6_addr *src); -static void sppp_gen_ip6_addr(struct sppp *sp, const struct in6_addr *src); -#endif -static void sppp_suggest_ip6_addr(struct sppp *sp, struct in6_addr *src); -#endif - -/* if_start () wrapper */ -static void sppp_ifstart (struct ifnet *ifp); - -/* our control protocol descriptors */ -static const struct cp lcp = { - PPP_LCP, IDX_LCP, CP_LCP, "lcp", - sppp_lcp_up, sppp_lcp_down, sppp_lcp_open, sppp_lcp_close, - sppp_lcp_TO, sppp_lcp_RCR, sppp_lcp_RCN_rej, sppp_lcp_RCN_nak, - sppp_lcp_tlu, sppp_lcp_tld, sppp_lcp_tls, sppp_lcp_tlf, - sppp_lcp_scr -}; - -static const struct cp ipcp = { - PPP_IPCP, IDX_IPCP, -#ifdef INET /* don't run IPCP if there's no IPv4 support */ - CP_NCP, -#else - 0, -#endif - "ipcp", - sppp_ipcp_up, sppp_ipcp_down, sppp_ipcp_open, sppp_ipcp_close, - sppp_ipcp_TO, sppp_ipcp_RCR, sppp_ipcp_RCN_rej, sppp_ipcp_RCN_nak, - sppp_ipcp_tlu, sppp_ipcp_tld, sppp_ipcp_tls, sppp_ipcp_tlf, - sppp_ipcp_scr -}; - -static const struct cp ipv6cp = { - PPP_IPV6CP, IDX_IPV6CP, -#ifdef INET6 /*don't run IPv6CP if there's no IPv6 support*/ - CP_NCP, -#else - 0, -#endif - "ipv6cp", - sppp_ipv6cp_up, sppp_ipv6cp_down, sppp_ipv6cp_open, sppp_ipv6cp_close, - sppp_ipv6cp_TO, sppp_ipv6cp_RCR, sppp_ipv6cp_RCN_rej, sppp_ipv6cp_RCN_nak, - sppp_ipv6cp_tlu, sppp_ipv6cp_tld, sppp_ipv6cp_tls, sppp_ipv6cp_tlf, - sppp_ipv6cp_scr -}; - -static const struct cp pap = { - PPP_PAP, IDX_PAP, CP_AUTH, "pap", - sppp_null, sppp_null, sppp_pap_open, sppp_pap_close, - sppp_pap_TO, 0, 0, 0, - sppp_pap_tlu, sppp_pap_tld, sppp_null, sppp_null, - sppp_pap_scr -}; - -static const struct cp chap = { - PPP_CHAP, IDX_CHAP, CP_AUTH, "chap", - sppp_null, sppp_null, sppp_chap_open, sppp_chap_close, - sppp_chap_TO, 0, 0, 0, - sppp_chap_tlu, sppp_chap_tld, sppp_null, sppp_null, - sppp_chap_scr -}; - -static const struct cp *cps[IDX_COUNT] = { - &lcp, /* IDX_LCP */ - &ipcp, /* IDX_IPCP */ - &ipv6cp, /* IDX_IPV6CP */ - &pap, /* IDX_PAP */ - &chap, /* IDX_CHAP */ -}; - -static void* -sppp_alloc(u_char type, struct ifnet *ifp) -{ - struct sppp *sp; - - sp = malloc(sizeof(struct sppp), M_SPPP, M_WAITOK | M_ZERO); - sp->pp_ifp = ifp; - - return (sp); -} - -static void -sppp_free(void *com, u_char type) -{ - - free(com, M_SPPP); -} - -static int -sppp_modevent(module_t mod, int type, void *unused) -{ - switch (type) { - case MOD_LOAD: - /* - * XXX: should probably be IFT_SPPP, but it's fairly - * harmless to allocate struct sppp's for non-sppp - * interfaces. - */ - - if_register_com_alloc(IFT_PPP, sppp_alloc, sppp_free); - break; - case MOD_UNLOAD: - /* if_deregister_com_alloc(IFT_PPP); */ - return EACCES; - default: - return EOPNOTSUPP; - } - return 0; -} -static moduledata_t spppmod = { - "sppp", - sppp_modevent, - 0 -}; -MODULE_VERSION(sppp, 1); -DECLARE_MODULE(sppp, spppmod, SI_SUB_DRIVERS, SI_ORDER_ANY); - -/* - * Exported functions, comprising our interface to the lower layer. - */ - -/* - * Process the received packet. - */ -void -sppp_input(struct ifnet *ifp, struct mbuf *m) -{ - struct ppp_header *h; - int isr = -1; - struct sppp *sp = IFP2SP(ifp); - int debug, do_account = 0; -#ifdef INET - int hlen, vjlen; - u_char *iphdr; -#endif - - SPPP_LOCK(sp); - debug = ifp->if_flags & IFF_DEBUG; - - if (ifp->if_flags & IFF_UP) - /* Count received bytes, add FCS and one flag */ - if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len + 3); - - if (m->m_pkthdr.len <= PPP_HEADER_LEN) { - /* Too small packet, drop it. */ - if (debug) - log(LOG_DEBUG, - SPP_FMT "input packet is too small, %d bytes\n", - SPP_ARGS(ifp), m->m_pkthdr.len); - drop: - m_freem (m); - SPPP_UNLOCK(sp); - drop2: - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); - return; - } - - if (sp->pp_mode == PP_FR) { - sppp_fr_input (sp, m); - SPPP_UNLOCK(sp); - return; - } - - /* Get PPP header. */ - h = mtod (m, struct ppp_header*); - m_adj (m, PPP_HEADER_LEN); - - switch (h->address) { - case PPP_ALLSTATIONS: - if (h->control != PPP_UI) - goto invalid; - if (sp->pp_mode == IFF_CISCO) { - if (debug) - log(LOG_DEBUG, - SPP_FMT "PPP packet in Cisco mode " - "\n", - SPP_ARGS(ifp), - h->address, h->control, ntohs(h->protocol)); - goto drop; - } - switch (ntohs (h->protocol)) { - default: - if (debug) - log(LOG_DEBUG, - SPP_FMT "rejecting protocol " - "\n", - SPP_ARGS(ifp), - h->address, h->control, ntohs(h->protocol)); - if (sp->state[IDX_LCP] == STATE_OPENED) - sppp_cp_send (sp, PPP_LCP, PROTO_REJ, - ++sp->pp_seq[IDX_LCP], m->m_pkthdr.len + 2, - &h->protocol); - if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1); - goto drop; - case PPP_LCP: - sppp_cp_input(&lcp, sp, m); - m_freem (m); - SPPP_UNLOCK(sp); - return; - case PPP_PAP: - if (sp->pp_phase >= PHASE_AUTHENTICATE) - sppp_pap_input(sp, m); - m_freem (m); - SPPP_UNLOCK(sp); - return; - case PPP_CHAP: - if (sp->pp_phase >= PHASE_AUTHENTICATE) - sppp_chap_input(sp, m); - m_freem (m); - SPPP_UNLOCK(sp); - return; -#ifdef INET - case PPP_IPCP: - if (sp->pp_phase == PHASE_NETWORK) - sppp_cp_input(&ipcp, sp, m); - m_freem (m); - SPPP_UNLOCK(sp); - return; - case PPP_IP: - if (sp->state[IDX_IPCP] == STATE_OPENED) { - isr = NETISR_IP; - } - do_account++; - break; - case PPP_VJ_COMP: - if (sp->state[IDX_IPCP] == STATE_OPENED) { - if ((vjlen = - sl_uncompress_tcp_core(mtod(m, u_char *), - m->m_len, m->m_len, - TYPE_COMPRESSED_TCP, - sp->pp_comp, - &iphdr, &hlen)) <= 0) { - if (debug) - log(LOG_INFO, - SPP_FMT "VJ uncompress failed on compressed packet\n", - SPP_ARGS(ifp)); - goto drop; - } - - /* - * Trim the VJ header off the packet, and prepend - * the uncompressed IP header (which will usually - * end up in two chained mbufs since there's not - * enough leading space in the existing mbuf). - */ - m_adj(m, vjlen); - M_PREPEND(m, hlen, M_NOWAIT); - if (m == NULL) { - SPPP_UNLOCK(sp); - goto drop2; - } - bcopy(iphdr, mtod(m, u_char *), hlen); - isr = NETISR_IP; - } - do_account++; - break; - case PPP_VJ_UCOMP: - if (sp->state[IDX_IPCP] == STATE_OPENED) { - if (sl_uncompress_tcp_core(mtod(m, u_char *), - m->m_len, m->m_len, - TYPE_UNCOMPRESSED_TCP, - sp->pp_comp, - &iphdr, &hlen) != 0) { - if (debug) - log(LOG_INFO, - SPP_FMT "VJ uncompress failed on uncompressed packet\n", - SPP_ARGS(ifp)); - goto drop; - } - isr = NETISR_IP; - } - do_account++; - break; -#endif -#ifdef INET6 - case PPP_IPV6CP: - if (sp->pp_phase == PHASE_NETWORK) - sppp_cp_input(&ipv6cp, sp, m); - m_freem (m); - SPPP_UNLOCK(sp); - return; - - case PPP_IPV6: - if (sp->state[IDX_IPV6CP] == STATE_OPENED) - isr = NETISR_IPV6; - do_account++; - break; -#endif - } - break; - case CISCO_MULTICAST: - case CISCO_UNICAST: - /* Don't check the control field here (RFC 1547). */ - if (sp->pp_mode != IFF_CISCO) { - if (debug) - log(LOG_DEBUG, - SPP_FMT "Cisco packet in PPP mode " - "\n", - SPP_ARGS(ifp), - h->address, h->control, ntohs(h->protocol)); - goto drop; - } - switch (ntohs (h->protocol)) { - default: - if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1); - goto invalid; - case CISCO_KEEPALIVE: - sppp_cisco_input (sp, m); - m_freem (m); - SPPP_UNLOCK(sp); - return; -#ifdef INET - case ETHERTYPE_IP: - isr = NETISR_IP; - do_account++; - break; -#endif -#ifdef INET6 - case ETHERTYPE_IPV6: - isr = NETISR_IPV6; - do_account++; - break; -#endif - } - break; - default: /* Invalid PPP packet. */ - invalid: - if (debug) - log(LOG_DEBUG, - SPP_FMT "invalid input packet " - "\n", - SPP_ARGS(ifp), - h->address, h->control, ntohs(h->protocol)); - goto drop; - } - - if (! (ifp->if_flags & IFF_UP) || isr == -1) - goto drop; - - SPPP_UNLOCK(sp); - M_SETFIB(m, ifp->if_fib); - /* Check queue. */ - if (netisr_queue(isr, m)) { /* (0) on success. */ - if (debug) - log(LOG_DEBUG, SPP_FMT "protocol queue overflow\n", - SPP_ARGS(ifp)); - goto drop2; - } - - if (do_account) - /* - * Do only account for network packets, not for control - * packets. This is used by some subsystems to detect - * idle lines. - */ - sp->pp_last_recv = time_uptime; -} - -static void -sppp_ifstart_sched(void *dummy) -{ - struct sppp *sp = dummy; - - sp->if_start(SP2IFP(sp)); -} - -/* if_start () wrapper function. We use it to schedule real if_start () for - * execution. We can't call it directly - */ -static void -sppp_ifstart(struct ifnet *ifp) -{ - struct sppp *sp = IFP2SP(ifp); - - if (SPPP_LOCK_OWNED(sp)) { - if (callout_pending(&sp->ifstart_callout)) - return; - callout_reset(&sp->ifstart_callout, 1, sppp_ifstart_sched, - (void *)sp); - } else { - sp->if_start(ifp); - } -} - -/* - * Enqueue transmit packet. - */ -static int -sppp_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, - struct route *ro) -{ - struct sppp *sp = IFP2SP(ifp); - struct ppp_header *h; - struct ifqueue *ifq = NULL; - int error, rv = 0; -#ifdef INET - int ipproto = PPP_IP; -#endif - int debug = ifp->if_flags & IFF_DEBUG; - int af = RO_GET_FAMILY(ro, dst); - - SPPP_LOCK(sp); - - if (!(ifp->if_flags & IFF_UP) || - (!(ifp->if_flags & IFF_AUTO) && - !(ifp->if_drv_flags & IFF_DRV_RUNNING))) { -#ifdef INET6 - drop: -#endif - m_freem (m); - SPPP_UNLOCK(sp); - return (ENETDOWN); - } - - if ((ifp->if_flags & IFF_AUTO) && - !(ifp->if_drv_flags & IFF_DRV_RUNNING)) { -#ifdef INET6 - /* - * XXX - * - * Hack to prevent the initialization-time generated - * IPv6 multicast packet to erroneously cause a - * dialout event in case IPv6 has been - * administratively disabled on that interface. - */ - if (af == AF_INET6 && - !(sp->confflags & CONF_ENABLE_IPV6)) - goto drop; -#endif - /* - * Interface is not yet running, but auto-dial. Need - * to start LCP for it. - */ - ifp->if_drv_flags |= IFF_DRV_RUNNING; - lcp.Open(sp); - } - -#ifdef INET - if (af == AF_INET) { - /* XXX Check mbuf length here? */ - struct ip *ip = mtod (m, struct ip*); - struct tcphdr *tcp = (struct tcphdr*) ((long*)ip + ip->ip_hl); - - /* - * When using dynamic local IP address assignment by using - * 0.0.0.0 as a local address, the first TCP session will - * not connect because the local TCP checksum is computed - * using 0.0.0.0 which will later become our real IP address - * so the TCP checksum computed at the remote end will - * become invalid. So we - * - don't let packets with src ip addr 0 thru - * - we flag TCP packets with src ip 0 as an error - */ - - if(ip->ip_src.s_addr == INADDR_ANY) /* -hm */ - { - m_freem(m); - SPPP_UNLOCK(sp); - if(ip->ip_p == IPPROTO_TCP) - return(EADDRNOTAVAIL); - else - return(0); - } - - /* - * Put low delay, telnet, rlogin and ftp control packets - * in front of the queue or let ALTQ take care. - */ - if (ALTQ_IS_ENABLED(&ifp->if_snd)) - ; - else if (_IF_QFULL(&sp->pp_fastq)) - ; - else if (ip->ip_tos & IPTOS_LOWDELAY) - ifq = &sp->pp_fastq; - else if (m->m_len < sizeof *ip + sizeof *tcp) - ; - else if (ip->ip_p != IPPROTO_TCP) - ; - else if (INTERACTIVE (ntohs (tcp->th_sport))) - ifq = &sp->pp_fastq; - else if (INTERACTIVE (ntohs (tcp->th_dport))) - ifq = &sp->pp_fastq; - - /* - * Do IP Header compression - */ - if (sp->pp_mode != IFF_CISCO && sp->pp_mode != PP_FR && - (sp->ipcp.flags & IPCP_VJ) && ip->ip_p == IPPROTO_TCP) - switch (sl_compress_tcp(m, ip, sp->pp_comp, - sp->ipcp.compress_cid)) { - case TYPE_COMPRESSED_TCP: - ipproto = PPP_VJ_COMP; - break; - case TYPE_UNCOMPRESSED_TCP: - ipproto = PPP_VJ_UCOMP; - break; - case TYPE_IP: - ipproto = PPP_IP; - break; - default: - m_freem(m); - SPPP_UNLOCK(sp); - return (EINVAL); - } - } -#endif - -#ifdef INET6 - if (af == AF_INET6) { - /* XXX do something tricky here? */ - } -#endif - - if (sp->pp_mode == PP_FR) { - /* Add frame relay header. */ - m = sppp_fr_header (sp, m, af); - if (! m) - goto nobufs; - goto out; - } - - /* - * Prepend general data packet PPP header. For now, IP only. - */ - M_PREPEND (m, PPP_HEADER_LEN, M_NOWAIT); - if (! m) { -nobufs: if (debug) - log(LOG_DEBUG, SPP_FMT "no memory for transmit header\n", - SPP_ARGS(ifp)); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - SPPP_UNLOCK(sp); - return (ENOBUFS); - } - /* - * May want to check size of packet - * (albeit due to the implementation it's always enough) - */ - h = mtod (m, struct ppp_header*); - if (sp->pp_mode == IFF_CISCO) { - h->address = CISCO_UNICAST; /* unicast address */ - h->control = 0; - } else { - h->address = PPP_ALLSTATIONS; /* broadcast address */ - h->control = PPP_UI; /* Unnumbered Info */ - } - - switch (af) { -#ifdef INET - case AF_INET: /* Internet Protocol */ - if (sp->pp_mode == IFF_CISCO) - h->protocol = htons (ETHERTYPE_IP); - else { - /* - * Don't choke with an ENETDOWN early. It's - * possible that we just started dialing out, - * so don't drop the packet immediately. If - * we notice that we run out of buffer space - * below, we will however remember that we are - * not ready to carry IP packets, and return - * ENETDOWN, as opposed to ENOBUFS. - */ - h->protocol = htons(ipproto); - if (sp->state[IDX_IPCP] != STATE_OPENED) - rv = ENETDOWN; - } - break; -#endif -#ifdef INET6 - case AF_INET6: /* Internet Protocol */ - if (sp->pp_mode == IFF_CISCO) - h->protocol = htons (ETHERTYPE_IPV6); - else { - /* - * Don't choke with an ENETDOWN early. It's - * possible that we just started dialing out, - * so don't drop the packet immediately. If - * we notice that we run out of buffer space - * below, we will however remember that we are - * not ready to carry IP packets, and return - * ENETDOWN, as opposed to ENOBUFS. - */ - h->protocol = htons(PPP_IPV6); - if (sp->state[IDX_IPV6CP] != STATE_OPENED) - rv = ENETDOWN; - } - break; -#endif - default: - m_freem (m); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - SPPP_UNLOCK(sp); - return (EAFNOSUPPORT); - } - - /* - * Queue message on interface, and start output if interface - * not yet active. - */ -out: - if (ifq != NULL) - error = !(IF_HANDOFF_ADJ(ifq, m, ifp, 3)); - else - IFQ_HANDOFF_ADJ(ifp, m, 3, error); - if (error) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - SPPP_UNLOCK(sp); - return (rv? rv: ENOBUFS); - } - SPPP_UNLOCK(sp); - /* - * Unlike in sppp_input(), we can always bump the timestamp - * here since sppp_output() is only called on behalf of - * network-layer traffic; control-layer traffic is handled - * by sppp_cp_send(). - */ - sp->pp_last_sent = time_uptime; - return (0); -} - -void -sppp_attach(struct ifnet *ifp) -{ - struct sppp *sp = IFP2SP(ifp); - - /* Initialize mtx lock */ - mtx_init(&sp->mtx, "sppp", MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); - - /* Initialize keepalive handler. */ - callout_init(&sp->keepalive_callout, 1); - callout_reset(&sp->keepalive_callout, hz * 10, sppp_keepalive, - (void *)sp); - - ifp->if_mtu = PP_MTU; - ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; - ifp->if_output = sppp_output; -#if 0 - sp->pp_flags = PP_KEEPALIVE; -#endif - ifp->if_snd.ifq_maxlen = 32; - sp->pp_fastq.ifq_maxlen = 32; - sp->pp_cpq.ifq_maxlen = 20; - sp->pp_loopcnt = 0; - sp->pp_alivecnt = 0; - bzero(&sp->pp_seq[0], sizeof(sp->pp_seq)); - bzero(&sp->pp_rseq[0], sizeof(sp->pp_rseq)); - sp->pp_phase = PHASE_DEAD; - sp->pp_up = sppp_pp_up; - sp->pp_down = sppp_pp_down; - if(!mtx_initialized(&sp->pp_cpq.ifq_mtx)) - mtx_init(&sp->pp_cpq.ifq_mtx, "sppp_cpq", NULL, MTX_DEF); - if(!mtx_initialized(&sp->pp_fastq.ifq_mtx)) - mtx_init(&sp->pp_fastq.ifq_mtx, "sppp_fastq", NULL, MTX_DEF); - sp->pp_last_recv = sp->pp_last_sent = time_uptime; - sp->confflags = 0; -#ifdef INET - sp->confflags |= CONF_ENABLE_VJ; -#endif -#ifdef INET6 - sp->confflags |= CONF_ENABLE_IPV6; -#endif - callout_init(&sp->ifstart_callout, 1); - sp->if_start = ifp->if_start; - ifp->if_start = sppp_ifstart; - sp->pp_comp = malloc(sizeof(struct slcompress), M_TEMP, M_WAITOK); - sl_compress_init(sp->pp_comp, -1); - sppp_lcp_init(sp); - sppp_ipcp_init(sp); - sppp_ipv6cp_init(sp); - sppp_pap_init(sp); - sppp_chap_init(sp); -} - -void -sppp_detach(struct ifnet *ifp) -{ - struct sppp *sp = IFP2SP(ifp); - int i; - - KASSERT(mtx_initialized(&sp->mtx), ("sppp mutex is not initialized")); - - /* Stop keepalive handler. */ - callout_drain(&sp->keepalive_callout); - - for (i = 0; i < IDX_COUNT; i++) { - callout_drain(&sp->ch[i]); - } - callout_drain(&sp->pap_my_to_ch); - - mtx_destroy(&sp->pp_cpq.ifq_mtx); - mtx_destroy(&sp->pp_fastq.ifq_mtx); - mtx_destroy(&sp->mtx); -} - -/* - * Flush the interface output queue. - */ -static void -sppp_flush_unlocked(struct ifnet *ifp) -{ - struct sppp *sp = IFP2SP(ifp); - - sppp_qflush ((struct ifqueue *)&SP2IFP(sp)->if_snd); - sppp_qflush (&sp->pp_fastq); - sppp_qflush (&sp->pp_cpq); -} - -void -sppp_flush(struct ifnet *ifp) -{ - struct sppp *sp = IFP2SP(ifp); - - SPPP_LOCK(sp); - sppp_flush_unlocked (ifp); - SPPP_UNLOCK(sp); -} - -/* - * Check if the output queue is empty. - */ -int -sppp_isempty(struct ifnet *ifp) -{ - struct sppp *sp = IFP2SP(ifp); - int empty; - - SPPP_LOCK(sp); - empty = !sp->pp_fastq.ifq_head && !sp->pp_cpq.ifq_head && - !SP2IFP(sp)->if_snd.ifq_head; - SPPP_UNLOCK(sp); - return (empty); -} - -/* - * Get next packet to send. - */ -struct mbuf * -sppp_dequeue(struct ifnet *ifp) -{ - struct sppp *sp = IFP2SP(ifp); - struct mbuf *m; - - SPPP_LOCK(sp); - /* - * Process only the control protocol queue until we have at - * least one NCP open. - * - * Do always serve all three queues in Cisco mode. - */ - IF_DEQUEUE(&sp->pp_cpq, m); - if (m == NULL && - (sppp_ncp_check(sp) || sp->pp_mode == IFF_CISCO || - sp->pp_mode == PP_FR)) { - IF_DEQUEUE(&sp->pp_fastq, m); - if (m == NULL) - IF_DEQUEUE (&SP2IFP(sp)->if_snd, m); - } - SPPP_UNLOCK(sp); - return m; -} - -/* - * Pick the next packet, do not remove it from the queue. - */ -struct mbuf * -sppp_pick(struct ifnet *ifp) -{ - struct sppp *sp = IFP2SP(ifp); - struct mbuf *m; - - SPPP_LOCK(sp); - - m = sp->pp_cpq.ifq_head; - if (m == NULL && - (sp->pp_phase == PHASE_NETWORK || - sp->pp_mode == IFF_CISCO || - sp->pp_mode == PP_FR)) - if ((m = sp->pp_fastq.ifq_head) == NULL) - m = SP2IFP(sp)->if_snd.ifq_head; - SPPP_UNLOCK(sp); - return (m); -} - -/* - * Process an ioctl request. Called on low priority level. - */ -int -sppp_ioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, void *data) -{ - struct ifreq *ifr = (struct ifreq*) data; - struct sppp *sp = IFP2SP(ifp); - int rv, going_up, going_down, newmode; - - SPPP_LOCK(sp); - rv = 0; - switch (cmd) { - case SIOCAIFADDR: - break; - - case SIOCSIFADDR: - /* set the interface "up" when assigning an IP address */ - ifp->if_flags |= IFF_UP; - /* FALLTHROUGH */ - - case SIOCSIFFLAGS: - going_up = ifp->if_flags & IFF_UP && - (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0; - going_down = (ifp->if_flags & IFF_UP) == 0 && - ifp->if_drv_flags & IFF_DRV_RUNNING; - - newmode = ifp->if_flags & IFF_PASSIVE; - if (!newmode) - newmode = ifp->if_flags & IFF_AUTO; - if (!newmode) - newmode = ifp->if_flags & IFF_CISCO; - ifp->if_flags &= ~(IFF_PASSIVE | IFF_AUTO | IFF_CISCO); - ifp->if_flags |= newmode; - - if (!newmode) - newmode = sp->pp_flags & PP_FR; - - if (newmode != sp->pp_mode) { - going_down = 1; - if (!going_up) - going_up = ifp->if_drv_flags & IFF_DRV_RUNNING; - } - - if (going_down) { - if (sp->pp_mode != IFF_CISCO && - sp->pp_mode != PP_FR) - lcp.Close(sp); - else if (sp->pp_tlf) - (sp->pp_tlf)(sp); - sppp_flush_unlocked(ifp); - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - sp->pp_mode = newmode; - } - - if (going_up) { - if (sp->pp_mode != IFF_CISCO && - sp->pp_mode != PP_FR) - lcp.Close(sp); - sp->pp_mode = newmode; - if (sp->pp_mode == 0) { - ifp->if_drv_flags |= IFF_DRV_RUNNING; - lcp.Open(sp); - } - if ((sp->pp_mode == IFF_CISCO) || - (sp->pp_mode == PP_FR)) { - if (sp->pp_tls) - (sp->pp_tls)(sp); - ifp->if_drv_flags |= IFF_DRV_RUNNING; - } - } - - break; - -#ifdef SIOCSIFMTU -#ifndef ifr_mtu -#define ifr_mtu ifr_metric -#endif - case SIOCSIFMTU: - if (ifr->ifr_mtu < 128 || ifr->ifr_mtu > sp->lcp.their_mru) - return (EINVAL); - ifp->if_mtu = ifr->ifr_mtu; - break; -#endif -#ifdef SLIOCSETMTU - case SLIOCSETMTU: - if (*(short*)data < 128 || *(short*)data > sp->lcp.their_mru) - return (EINVAL); - ifp->if_mtu = *(short*)data; - break; -#endif -#ifdef SIOCGIFMTU - case SIOCGIFMTU: - ifr->ifr_mtu = ifp->if_mtu; - break; -#endif -#ifdef SLIOCGETMTU - case SLIOCGETMTU: - *(short*)data = ifp->if_mtu; - break; -#endif - case SIOCADDMULTI: - case SIOCDELMULTI: - break; - - case SIOCGIFGENERIC: - case SIOCSIFGENERIC: - rv = sppp_params(sp, cmd, data); - break; - - default: - rv = ENOTTY; - } - SPPP_UNLOCK(sp); - return rv; -} - -/* - * Cisco framing implementation. - */ - -/* - * Handle incoming Cisco keepalive protocol packets. - */ -static void -sppp_cisco_input(struct sppp *sp, struct mbuf *m) -{ - STDDCL; - struct cisco_packet *h; - u_long me, mymask; - - if (m->m_pkthdr.len < CISCO_PACKET_LEN) { - if (debug) - log(LOG_DEBUG, - SPP_FMT "cisco invalid packet length: %d bytes\n", - SPP_ARGS(ifp), m->m_pkthdr.len); - return; - } - h = mtod (m, struct cisco_packet*); - if (debug) - log(LOG_DEBUG, - SPP_FMT "cisco input: %d bytes " - "<0x%lx 0x%lx 0x%lx 0x%x 0x%x-0x%x>\n", - SPP_ARGS(ifp), m->m_pkthdr.len, - (u_long)ntohl (h->type), (u_long)h->par1, (u_long)h->par2, (u_int)h->rel, - (u_int)h->time0, (u_int)h->time1); - switch (ntohl (h->type)) { - default: - if (debug) - log(-1, SPP_FMT "cisco unknown packet type: 0x%lx\n", - SPP_ARGS(ifp), (u_long)ntohl (h->type)); - break; - case CISCO_ADDR_REPLY: - /* Reply on address request, ignore */ - break; - case CISCO_KEEPALIVE_REQ: - sp->pp_alivecnt = 0; - sp->pp_rseq[IDX_LCP] = ntohl (h->par1); - if (sp->pp_seq[IDX_LCP] == sp->pp_rseq[IDX_LCP]) { - /* Local and remote sequence numbers are equal. - * Probably, the line is in loopback mode. */ - if (sp->pp_loopcnt >= MAXALIVECNT) { - printf (SPP_FMT "loopback\n", - SPP_ARGS(ifp)); - sp->pp_loopcnt = 0; - if (ifp->if_flags & IFF_UP) { - if_down (ifp); - sppp_qflush (&sp->pp_cpq); - } - } - ++sp->pp_loopcnt; - - /* Generate new local sequence number */ - sp->pp_seq[IDX_LCP] = random(); - break; - } - sp->pp_loopcnt = 0; - if (! (ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING)) { - if_up(ifp); - printf (SPP_FMT "up\n", SPP_ARGS(ifp)); - } - break; - case CISCO_ADDR_REQ: - sppp_get_ip_addrs(sp, &me, 0, &mymask); - if (me != 0L) - sppp_cisco_send(sp, CISCO_ADDR_REPLY, me, mymask); - break; - } -} - -/* - * Send Cisco keepalive packet. - */ -static void -sppp_cisco_send(struct sppp *sp, int type, long par1, long par2) -{ - STDDCL; - struct ppp_header *h; - struct cisco_packet *ch; - struct mbuf *m; - struct timeval tv; - - getmicrouptime(&tv); - - MGETHDR (m, M_NOWAIT, MT_DATA); - if (! m) - return; - m->m_pkthdr.len = m->m_len = PPP_HEADER_LEN + CISCO_PACKET_LEN; - m->m_pkthdr.rcvif = 0; - - h = mtod (m, struct ppp_header*); - h->address = CISCO_MULTICAST; - h->control = 0; - h->protocol = htons (CISCO_KEEPALIVE); - - ch = (struct cisco_packet*) (h + 1); - ch->type = htonl (type); - ch->par1 = htonl (par1); - ch->par2 = htonl (par2); - ch->rel = -1; - - ch->time0 = htons ((u_short) (tv.tv_sec >> 16)); - ch->time1 = htons ((u_short) tv.tv_sec); - - if (debug) - log(LOG_DEBUG, - SPP_FMT "cisco output: <0x%lx 0x%lx 0x%lx 0x%x 0x%x-0x%x>\n", - SPP_ARGS(ifp), (u_long)ntohl (ch->type), (u_long)ch->par1, - (u_long)ch->par2, (u_int)ch->rel, (u_int)ch->time0, (u_int)ch->time1); - - if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3)) - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); -} - -/* - * PPP protocol implementation. - */ - -/* - * Send PPP control protocol packet. - */ -static void -sppp_cp_send(struct sppp *sp, u_short proto, u_char type, - u_char ident, u_short len, void *data) -{ - STDDCL; - struct ppp_header *h; - struct lcp_header *lh; - struct mbuf *m; - - if (len > MHLEN - PPP_HEADER_LEN - LCP_HEADER_LEN) - len = MHLEN - PPP_HEADER_LEN - LCP_HEADER_LEN; - MGETHDR (m, M_NOWAIT, MT_DATA); - if (! m) - return; - m->m_pkthdr.len = m->m_len = PPP_HEADER_LEN + LCP_HEADER_LEN + len; - m->m_pkthdr.rcvif = 0; - - h = mtod (m, struct ppp_header*); - h->address = PPP_ALLSTATIONS; /* broadcast address */ - h->control = PPP_UI; /* Unnumbered Info */ - h->protocol = htons (proto); /* Link Control Protocol */ - - lh = (struct lcp_header*) (h + 1); - lh->type = type; - lh->ident = ident; - lh->len = htons (LCP_HEADER_LEN + len); - if (len) - bcopy (data, lh+1, len); - - if (debug) { - log(LOG_DEBUG, SPP_FMT "%s output <%s id=0x%x len=%d", - SPP_ARGS(ifp), - sppp_proto_name(proto), - sppp_cp_type_name (lh->type), lh->ident, - ntohs (lh->len)); - sppp_print_bytes ((u_char*) (lh+1), len); - log(-1, ">\n"); - } - if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3)) - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); -} - -/* - * Handle incoming PPP control protocol packets. - */ -static void -sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m) -{ - STDDCL; - struct lcp_header *h; - int len = m->m_pkthdr.len; - int rv; - u_char *p; - - if (len < 4) { - if (debug) - log(LOG_DEBUG, - SPP_FMT "%s invalid packet length: %d bytes\n", - SPP_ARGS(ifp), cp->name, len); - return; - } - h = mtod (m, struct lcp_header*); - if (debug) { - log(LOG_DEBUG, - SPP_FMT "%s input(%s): <%s id=0x%x len=%d", - SPP_ARGS(ifp), cp->name, - sppp_state_name(sp->state[cp->protoidx]), - sppp_cp_type_name (h->type), h->ident, ntohs (h->len)); - sppp_print_bytes ((u_char*) (h+1), len-4); - log(-1, ">\n"); - } - if (len > ntohs (h->len)) - len = ntohs (h->len); - p = (u_char *)(h + 1); - switch (h->type) { - case CONF_REQ: - if (len < 4) { - if (debug) - log(-1, SPP_FMT "%s invalid conf-req length %d\n", - SPP_ARGS(ifp), cp->name, - len); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - break; - } - /* handle states where RCR doesn't get a SCA/SCN */ - switch (sp->state[cp->protoidx]) { - case STATE_CLOSING: - case STATE_STOPPING: - return; - case STATE_CLOSED: - sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, - 0, 0); - return; - } - rv = (cp->RCR)(sp, h, len); - switch (sp->state[cp->protoidx]) { - case STATE_OPENED: - (cp->tld)(sp); - (cp->scr)(sp); - /* FALLTHROUGH */ - case STATE_ACK_SENT: - case STATE_REQ_SENT: - /* - * sppp_cp_change_state() have the side effect of - * restarting the timeouts. We want to avoid that - * if the state don't change, otherwise we won't - * ever timeout and resend a configuration request - * that got lost. - */ - if (sp->state[cp->protoidx] == (rv ? STATE_ACK_SENT: - STATE_REQ_SENT)) - break; - sppp_cp_change_state(cp, sp, rv? - STATE_ACK_SENT: STATE_REQ_SENT); - break; - case STATE_STOPPED: - sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; - (cp->scr)(sp); - sppp_cp_change_state(cp, sp, rv? - STATE_ACK_SENT: STATE_REQ_SENT); - break; - case STATE_ACK_RCVD: - if (rv) { - sppp_cp_change_state(cp, sp, STATE_OPENED); - if (debug) - log(LOG_DEBUG, SPP_FMT "%s tlu\n", - SPP_ARGS(ifp), - cp->name); - (cp->tlu)(sp); - } else - sppp_cp_change_state(cp, sp, STATE_ACK_RCVD); - break; - default: - printf(SPP_FMT "%s illegal %s in state %s\n", - SPP_ARGS(ifp), cp->name, - sppp_cp_type_name(h->type), - sppp_state_name(sp->state[cp->protoidx])); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - } - break; - case CONF_ACK: - if (h->ident != sp->confid[cp->protoidx]) { - if (debug) - log(-1, SPP_FMT "%s id mismatch 0x%x != 0x%x\n", - SPP_ARGS(ifp), cp->name, - h->ident, sp->confid[cp->protoidx]); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - break; - } - switch (sp->state[cp->protoidx]) { - case STATE_CLOSED: - case STATE_STOPPED: - sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0); - break; - case STATE_CLOSING: - case STATE_STOPPING: - break; - case STATE_REQ_SENT: - sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; - sppp_cp_change_state(cp, sp, STATE_ACK_RCVD); - break; - case STATE_OPENED: - (cp->tld)(sp); - /* FALLTHROUGH */ - case STATE_ACK_RCVD: - (cp->scr)(sp); - sppp_cp_change_state(cp, sp, STATE_REQ_SENT); - break; - case STATE_ACK_SENT: - sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; - sppp_cp_change_state(cp, sp, STATE_OPENED); - if (debug) - log(LOG_DEBUG, SPP_FMT "%s tlu\n", - SPP_ARGS(ifp), cp->name); - (cp->tlu)(sp); - break; - default: - printf(SPP_FMT "%s illegal %s in state %s\n", - SPP_ARGS(ifp), cp->name, - sppp_cp_type_name(h->type), - sppp_state_name(sp->state[cp->protoidx])); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - } - break; - case CONF_NAK: - case CONF_REJ: - if (h->ident != sp->confid[cp->protoidx]) { - if (debug) - log(-1, SPP_FMT "%s id mismatch 0x%x != 0x%x\n", - SPP_ARGS(ifp), cp->name, - h->ident, sp->confid[cp->protoidx]); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - break; - } - if (h->type == CONF_NAK) - (cp->RCN_nak)(sp, h, len); - else /* CONF_REJ */ - (cp->RCN_rej)(sp, h, len); - - switch (sp->state[cp->protoidx]) { - case STATE_CLOSED: - case STATE_STOPPED: - sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0); - break; - case STATE_REQ_SENT: - case STATE_ACK_SENT: - sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; - /* - * Slow things down a bit if we think we might be - * in loopback. Depend on the timeout to send the - * next configuration request. - */ - if (sp->pp_loopcnt) - break; - (cp->scr)(sp); - break; - case STATE_OPENED: - (cp->tld)(sp); - /* FALLTHROUGH */ - case STATE_ACK_RCVD: - sppp_cp_change_state(cp, sp, STATE_REQ_SENT); - (cp->scr)(sp); - break; - case STATE_CLOSING: - case STATE_STOPPING: - break; - default: - printf(SPP_FMT "%s illegal %s in state %s\n", - SPP_ARGS(ifp), cp->name, - sppp_cp_type_name(h->type), - sppp_state_name(sp->state[cp->protoidx])); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - } - break; - - case TERM_REQ: - switch (sp->state[cp->protoidx]) { - case STATE_ACK_RCVD: - case STATE_ACK_SENT: - sppp_cp_change_state(cp, sp, STATE_REQ_SENT); - /* FALLTHROUGH */ - case STATE_CLOSED: - case STATE_STOPPED: - case STATE_CLOSING: - case STATE_STOPPING: - case STATE_REQ_SENT: - sta: - /* Send Terminate-Ack packet. */ - if (debug) - log(LOG_DEBUG, SPP_FMT "%s send terminate-ack\n", - SPP_ARGS(ifp), cp->name); - sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0); - break; - case STATE_OPENED: - (cp->tld)(sp); - sp->rst_counter[cp->protoidx] = 0; - sppp_cp_change_state(cp, sp, STATE_STOPPING); - goto sta; - break; - default: - printf(SPP_FMT "%s illegal %s in state %s\n", - SPP_ARGS(ifp), cp->name, - sppp_cp_type_name(h->type), - sppp_state_name(sp->state[cp->protoidx])); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - } - break; - case TERM_ACK: - switch (sp->state[cp->protoidx]) { - case STATE_CLOSED: - case STATE_STOPPED: - case STATE_REQ_SENT: - case STATE_ACK_SENT: - break; - case STATE_CLOSING: - sppp_cp_change_state(cp, sp, STATE_CLOSED); - (cp->tlf)(sp); - break; - case STATE_STOPPING: - sppp_cp_change_state(cp, sp, STATE_STOPPED); - (cp->tlf)(sp); - break; - case STATE_ACK_RCVD: - sppp_cp_change_state(cp, sp, STATE_REQ_SENT); - break; - case STATE_OPENED: - (cp->tld)(sp); - (cp->scr)(sp); - sppp_cp_change_state(cp, sp, STATE_ACK_RCVD); - break; - default: - printf(SPP_FMT "%s illegal %s in state %s\n", - SPP_ARGS(ifp), cp->name, - sppp_cp_type_name(h->type), - sppp_state_name(sp->state[cp->protoidx])); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - } - break; - case CODE_REJ: - /* XXX catastrophic rejects (RXJ-) aren't handled yet. */ - log(LOG_INFO, - SPP_FMT "%s: ignoring RXJ (%s) for proto 0x%x, " - "danger will robinson\n", - SPP_ARGS(ifp), cp->name, - sppp_cp_type_name(h->type), ntohs(*((u_short *)p))); - switch (sp->state[cp->protoidx]) { - case STATE_CLOSED: - case STATE_STOPPED: - case STATE_REQ_SENT: - case STATE_ACK_SENT: - case STATE_CLOSING: - case STATE_STOPPING: - case STATE_OPENED: - break; - case STATE_ACK_RCVD: - sppp_cp_change_state(cp, sp, STATE_REQ_SENT); - break; - default: - printf(SPP_FMT "%s illegal %s in state %s\n", - SPP_ARGS(ifp), cp->name, - sppp_cp_type_name(h->type), - sppp_state_name(sp->state[cp->protoidx])); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - } - break; - case PROTO_REJ: - { - int catastrophic; - const struct cp *upper; - int i; - u_int16_t proto; - - catastrophic = 0; - upper = NULL; - proto = ntohs(*((u_int16_t *)p)); - for (i = 0; i < IDX_COUNT; i++) { - if (cps[i]->proto == proto) { - upper = cps[i]; - break; - } - } - if (upper == NULL) - catastrophic++; - - if (catastrophic || debug) - log(catastrophic? LOG_INFO: LOG_DEBUG, - SPP_FMT "%s: RXJ%c (%s) for proto 0x%x (%s/%s)\n", - SPP_ARGS(ifp), cp->name, catastrophic ? '-' : '+', - sppp_cp_type_name(h->type), proto, - upper ? upper->name : "unknown", - upper ? sppp_state_name(sp->state[upper->protoidx]) : "?"); - - /* - * if we got RXJ+ against conf-req, the peer does not implement - * this particular protocol type. terminate the protocol. - */ - if (upper && !catastrophic) { - if (sp->state[upper->protoidx] == STATE_REQ_SENT) { - upper->Close(sp); - break; - } - } - - /* XXX catastrophic rejects (RXJ-) aren't handled yet. */ - switch (sp->state[cp->protoidx]) { - case STATE_CLOSED: - case STATE_STOPPED: - case STATE_REQ_SENT: - case STATE_ACK_SENT: - case STATE_CLOSING: - case STATE_STOPPING: - case STATE_OPENED: - break; - case STATE_ACK_RCVD: - sppp_cp_change_state(cp, sp, STATE_REQ_SENT); - break; - default: - printf(SPP_FMT "%s illegal %s in state %s\n", - SPP_ARGS(ifp), cp->name, - sppp_cp_type_name(h->type), - sppp_state_name(sp->state[cp->protoidx])); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - } - break; - } - case DISC_REQ: - if (cp->proto != PPP_LCP) - goto illegal; - /* Discard the packet. */ - break; - case ECHO_REQ: - if (cp->proto != PPP_LCP) - goto illegal; - if (sp->state[cp->protoidx] != STATE_OPENED) { - if (debug) - log(-1, SPP_FMT "lcp echo req but lcp closed\n", - SPP_ARGS(ifp)); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - break; - } - if (len < 8) { - if (debug) - log(-1, SPP_FMT "invalid lcp echo request " - "packet length: %d bytes\n", - SPP_ARGS(ifp), len); - break; - } - if ((sp->lcp.opts & (1 << LCP_OPT_MAGIC)) && - ntohl (*(long*)(h+1)) == sp->lcp.magic) { - /* Line loopback mode detected. */ - printf(SPP_FMT "loopback\n", SPP_ARGS(ifp)); - sp->pp_loopcnt = MAXALIVECNT * 5; - if_down (ifp); - sppp_qflush (&sp->pp_cpq); - - /* Shut down the PPP link. */ - /* XXX */ - lcp.Down(sp); - lcp.Up(sp); - break; - } - *(long*)(h+1) = htonl (sp->lcp.magic); - if (debug) - log(-1, SPP_FMT "got lcp echo req, sending echo rep\n", - SPP_ARGS(ifp)); - sppp_cp_send (sp, PPP_LCP, ECHO_REPLY, h->ident, len-4, h+1); - break; - case ECHO_REPLY: - if (cp->proto != PPP_LCP) - goto illegal; - if (h->ident != sp->lcp.echoid) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - break; - } - if (len < 8) { - if (debug) - log(-1, SPP_FMT "lcp invalid echo reply " - "packet length: %d bytes\n", - SPP_ARGS(ifp), len); - break; - } - if (debug) - log(-1, SPP_FMT "lcp got echo rep\n", - SPP_ARGS(ifp)); - if (!(sp->lcp.opts & (1 << LCP_OPT_MAGIC)) || - ntohl (*(long*)(h+1)) != sp->lcp.magic) - sp->pp_alivecnt = 0; - break; - default: - /* Unknown packet type -- send Code-Reject packet. */ - illegal: - if (debug) - log(-1, SPP_FMT "%s send code-rej for 0x%x\n", - SPP_ARGS(ifp), cp->name, h->type); - sppp_cp_send(sp, cp->proto, CODE_REJ, - ++sp->pp_seq[cp->protoidx], m->m_pkthdr.len, h); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - } -} - -/* - * The generic part of all Up/Down/Open/Close/TO event handlers. - * Basically, the state transition handling in the automaton. - */ -static void -sppp_up_event(const struct cp *cp, struct sppp *sp) -{ - STDDCL; - - if (debug) - log(LOG_DEBUG, SPP_FMT "%s up(%s)\n", - SPP_ARGS(ifp), cp->name, - sppp_state_name(sp->state[cp->protoidx])); - - switch (sp->state[cp->protoidx]) { - case STATE_INITIAL: - sppp_cp_change_state(cp, sp, STATE_CLOSED); - break; - case STATE_STARTING: - sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; - (cp->scr)(sp); - sppp_cp_change_state(cp, sp, STATE_REQ_SENT); - break; - default: - printf(SPP_FMT "%s illegal up in state %s\n", - SPP_ARGS(ifp), cp->name, - sppp_state_name(sp->state[cp->protoidx])); - } -} - -static void -sppp_down_event(const struct cp *cp, struct sppp *sp) -{ - STDDCL; - - if (debug) - log(LOG_DEBUG, SPP_FMT "%s down(%s)\n", - SPP_ARGS(ifp), cp->name, - sppp_state_name(sp->state[cp->protoidx])); - - switch (sp->state[cp->protoidx]) { - case STATE_CLOSED: - case STATE_CLOSING: - sppp_cp_change_state(cp, sp, STATE_INITIAL); - break; - case STATE_STOPPED: - sppp_cp_change_state(cp, sp, STATE_STARTING); - (cp->tls)(sp); - break; - case STATE_STOPPING: - case STATE_REQ_SENT: - case STATE_ACK_RCVD: - case STATE_ACK_SENT: - sppp_cp_change_state(cp, sp, STATE_STARTING); - break; - case STATE_OPENED: - (cp->tld)(sp); - sppp_cp_change_state(cp, sp, STATE_STARTING); - break; - default: - printf(SPP_FMT "%s illegal down in state %s\n", - SPP_ARGS(ifp), cp->name, - sppp_state_name(sp->state[cp->protoidx])); - } -} - -static void -sppp_open_event(const struct cp *cp, struct sppp *sp) -{ - STDDCL; - - if (debug) - log(LOG_DEBUG, SPP_FMT "%s open(%s)\n", - SPP_ARGS(ifp), cp->name, - sppp_state_name(sp->state[cp->protoidx])); - - switch (sp->state[cp->protoidx]) { - case STATE_INITIAL: - sppp_cp_change_state(cp, sp, STATE_STARTING); - (cp->tls)(sp); - break; - case STATE_STARTING: - break; - case STATE_CLOSED: - sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; - (cp->scr)(sp); - sppp_cp_change_state(cp, sp, STATE_REQ_SENT); - break; - case STATE_STOPPED: - /* - * Try escaping stopped state. This seems to bite - * people occasionally, in particular for IPCP, - * presumably following previous IPCP negotiation - * aborts. Somehow, we must have missed a Down event - * which would have caused a transition into starting - * state, so as a bandaid we force the Down event now. - * This effectively implements (something like the) - * `restart' option mentioned in the state transition - * table of RFC 1661. - */ - sppp_cp_change_state(cp, sp, STATE_STARTING); - (cp->tls)(sp); - break; - case STATE_STOPPING: - case STATE_REQ_SENT: - case STATE_ACK_RCVD: - case STATE_ACK_SENT: - case STATE_OPENED: - break; - case STATE_CLOSING: - sppp_cp_change_state(cp, sp, STATE_STOPPING); - break; - } -} - -static void -sppp_close_event(const struct cp *cp, struct sppp *sp) -{ - STDDCL; - - if (debug) - log(LOG_DEBUG, SPP_FMT "%s close(%s)\n", - SPP_ARGS(ifp), cp->name, - sppp_state_name(sp->state[cp->protoidx])); - - switch (sp->state[cp->protoidx]) { - case STATE_INITIAL: - case STATE_CLOSED: - case STATE_CLOSING: - break; - case STATE_STARTING: - sppp_cp_change_state(cp, sp, STATE_INITIAL); - (cp->tlf)(sp); - break; - case STATE_STOPPED: - sppp_cp_change_state(cp, sp, STATE_CLOSED); - break; - case STATE_STOPPING: - sppp_cp_change_state(cp, sp, STATE_CLOSING); - break; - case STATE_OPENED: - (cp->tld)(sp); - /* FALLTHROUGH */ - case STATE_REQ_SENT: - case STATE_ACK_RCVD: - case STATE_ACK_SENT: - sp->rst_counter[cp->protoidx] = sp->lcp.max_terminate; - sppp_cp_send(sp, cp->proto, TERM_REQ, - ++sp->pp_seq[cp->protoidx], 0, 0); - sppp_cp_change_state(cp, sp, STATE_CLOSING); - break; - } -} - -static void -sppp_to_event(const struct cp *cp, struct sppp *sp) -{ - STDDCL; - - SPPP_LOCK(sp); - if (debug) - log(LOG_DEBUG, SPP_FMT "%s TO(%s) rst_counter = %d\n", - SPP_ARGS(ifp), cp->name, - sppp_state_name(sp->state[cp->protoidx]), - sp->rst_counter[cp->protoidx]); - - if (--sp->rst_counter[cp->protoidx] < 0) - /* TO- event */ - switch (sp->state[cp->protoidx]) { - case STATE_CLOSING: - sppp_cp_change_state(cp, sp, STATE_CLOSED); - (cp->tlf)(sp); - break; - case STATE_STOPPING: - sppp_cp_change_state(cp, sp, STATE_STOPPED); - (cp->tlf)(sp); - break; - case STATE_REQ_SENT: - case STATE_ACK_RCVD: - case STATE_ACK_SENT: - sppp_cp_change_state(cp, sp, STATE_STOPPED); - (cp->tlf)(sp); - break; - } - else - /* TO+ event */ - switch (sp->state[cp->protoidx]) { - case STATE_CLOSING: - case STATE_STOPPING: - sppp_cp_send(sp, cp->proto, TERM_REQ, - ++sp->pp_seq[cp->protoidx], 0, 0); - callout_reset(&sp->ch[cp->protoidx], sp->lcp.timeout, - cp->TO, (void *)sp); - break; - case STATE_REQ_SENT: - case STATE_ACK_RCVD: - (cp->scr)(sp); - /* sppp_cp_change_state() will restart the timer */ - sppp_cp_change_state(cp, sp, STATE_REQ_SENT); - break; - case STATE_ACK_SENT: - (cp->scr)(sp); - callout_reset(&sp->ch[cp->protoidx], sp->lcp.timeout, - cp->TO, (void *)sp); - break; - } - - SPPP_UNLOCK(sp); -} - -/* - * Change the state of a control protocol in the state automaton. - * Takes care of starting/stopping the restart timer. - */ -static void -sppp_cp_change_state(const struct cp *cp, struct sppp *sp, int newstate) -{ - sp->state[cp->protoidx] = newstate; - - callout_stop (&sp->ch[cp->protoidx]); - - switch (newstate) { - case STATE_INITIAL: - case STATE_STARTING: - case STATE_CLOSED: - case STATE_STOPPED: - case STATE_OPENED: - break; - case STATE_CLOSING: - case STATE_STOPPING: - case STATE_REQ_SENT: - case STATE_ACK_RCVD: - case STATE_ACK_SENT: - callout_reset(&sp->ch[cp->protoidx], sp->lcp.timeout, - cp->TO, (void *)sp); - break; - } -} - -/* - *--------------------------------------------------------------------------* - * * - * The LCP implementation. * - * * - *--------------------------------------------------------------------------* - */ -static void -sppp_pp_up(struct sppp *sp) -{ - SPPP_LOCK(sp); - lcp.Up(sp); - SPPP_UNLOCK(sp); -} - -static void -sppp_pp_down(struct sppp *sp) -{ - SPPP_LOCK(sp); - lcp.Down(sp); - SPPP_UNLOCK(sp); -} - -static void -sppp_lcp_init(struct sppp *sp) -{ - sp->lcp.opts = (1 << LCP_OPT_MAGIC); - sp->lcp.magic = 0; - sp->state[IDX_LCP] = STATE_INITIAL; - sp->fail_counter[IDX_LCP] = 0; - sp->pp_seq[IDX_LCP] = 0; - sp->pp_rseq[IDX_LCP] = 0; - sp->lcp.protos = 0; - sp->lcp.mru = sp->lcp.their_mru = PP_MTU; - - /* Note that these values are relevant for all control protocols */ - sp->lcp.timeout = 3 * hz; - sp->lcp.max_terminate = 2; - sp->lcp.max_configure = 10; - sp->lcp.max_failure = 10; - callout_init(&sp->ch[IDX_LCP], 1); -} - -static void -sppp_lcp_up(struct sppp *sp) -{ - STDDCL; - - sp->pp_alivecnt = 0; - sp->lcp.opts = (1 << LCP_OPT_MAGIC); - sp->lcp.magic = 0; - sp->lcp.protos = 0; - sp->lcp.mru = sp->lcp.their_mru = PP_MTU; - /* - * If we are authenticator, negotiate LCP_AUTH - */ - if (sp->hisauth.proto != 0) - sp->lcp.opts |= (1 << LCP_OPT_AUTH_PROTO); - else - sp->lcp.opts &= ~(1 << LCP_OPT_AUTH_PROTO); - sp->pp_flags &= ~PP_NEEDAUTH; - /* - * If this interface is passive or dial-on-demand, and we are - * still in Initial state, it means we've got an incoming - * call. Activate the interface. - */ - if ((ifp->if_flags & (IFF_AUTO | IFF_PASSIVE)) != 0) { - if (debug) - log(LOG_DEBUG, - SPP_FMT "Up event", SPP_ARGS(ifp)); - ifp->if_drv_flags |= IFF_DRV_RUNNING; - if (sp->state[IDX_LCP] == STATE_INITIAL) { - if (debug) - log(-1, "(incoming call)\n"); - sp->pp_flags |= PP_CALLIN; - lcp.Open(sp); - } else if (debug) - log(-1, "\n"); - } else if ((ifp->if_flags & (IFF_AUTO | IFF_PASSIVE)) == 0 && - (sp->state[IDX_LCP] == STATE_INITIAL)) { - ifp->if_drv_flags |= IFF_DRV_RUNNING; - lcp.Open(sp); - } - - sppp_up_event(&lcp, sp); -} - -static void -sppp_lcp_down(struct sppp *sp) -{ - STDDCL; - - sppp_down_event(&lcp, sp); - - /* - * If this is neither a dial-on-demand nor a passive - * interface, simulate an ``ifconfig down'' action, so the - * administrator can force a redial by another ``ifconfig - * up''. XXX For leased line operation, should we immediately - * try to reopen the connection here? - */ - if ((ifp->if_flags & (IFF_AUTO | IFF_PASSIVE)) == 0) { - log(LOG_INFO, - SPP_FMT "Down event, taking interface down.\n", - SPP_ARGS(ifp)); - if_down(ifp); - } else { - if (debug) - log(LOG_DEBUG, - SPP_FMT "Down event (carrier loss)\n", - SPP_ARGS(ifp)); - sp->pp_flags &= ~PP_CALLIN; - if (sp->state[IDX_LCP] != STATE_INITIAL) - lcp.Close(sp); - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - } -} - -static void -sppp_lcp_open(struct sppp *sp) -{ - sppp_open_event(&lcp, sp); -} - -static void -sppp_lcp_close(struct sppp *sp) -{ - sppp_close_event(&lcp, sp); -} - -static void -sppp_lcp_TO(void *cookie) -{ - sppp_to_event(&lcp, (struct sppp *)cookie); -} - -/* - * Analyze a configure request. Return true if it was agreeable, and - * caused action sca, false if it has been rejected or nak'ed, and - * caused action scn. (The return value is used to make the state - * transition decision in the state automaton.) - */ -static int -sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len) -{ - STDDCL; - u_char *buf, *r, *p; - int origlen, rlen; - u_long nmagic; - u_short authproto; - - len -= 4; - origlen = len; - buf = r = malloc (len, M_TEMP, M_NOWAIT); - if (! buf) - return (0); - - if (debug) - log(LOG_DEBUG, SPP_FMT "lcp parse opts: ", - SPP_ARGS(ifp)); - - /* pass 1: check for things that need to be rejected */ - p = (void*) (h+1); - for (rlen=0; len >= 2 && p[1] >= 2 && len >= p[1]; - len-=p[1], p+=p[1]) { - if (debug) - log(-1, " %s ", sppp_lcp_opt_name(*p)); - switch (*p) { - case LCP_OPT_MAGIC: - /* Magic number. */ - if (len >= 6 && p[1] == 6) - continue; - if (debug) - log(-1, "[invalid] "); - break; - case LCP_OPT_ASYNC_MAP: - /* Async control character map. */ - if (len >= 6 && p[1] == 6) - continue; - if (debug) - log(-1, "[invalid] "); - break; - case LCP_OPT_MRU: - /* Maximum receive unit. */ - if (len >= 4 && p[1] == 4) - continue; - if (debug) - log(-1, "[invalid] "); - break; - case LCP_OPT_AUTH_PROTO: - if (len < 4) { - if (debug) - log(-1, "[invalid] "); - break; - } - authproto = (p[2] << 8) + p[3]; - if (authproto == PPP_CHAP && p[1] != 5) { - if (debug) - log(-1, "[invalid chap len] "); - break; - } - if (sp->myauth.proto == 0) { - /* we are not configured to do auth */ - if (debug) - log(-1, "[not configured] "); - break; - } - /* - * Remote want us to authenticate, remember this, - * so we stay in PHASE_AUTHENTICATE after LCP got - * up. - */ - sp->pp_flags |= PP_NEEDAUTH; - continue; - default: - /* Others not supported. */ - if (debug) - log(-1, "[rej] "); - break; - } - /* Add the option to rejected list. */ - bcopy (p, r, p[1]); - r += p[1]; - rlen += p[1]; - } - if (rlen) { - if (debug) - log(-1, " send conf-rej\n"); - sppp_cp_send (sp, PPP_LCP, CONF_REJ, h->ident, rlen, buf); - return 0; - } else if (debug) - log(-1, "\n"); - - /* - * pass 2: check for option values that are unacceptable and - * thus require to be nak'ed. - */ - if (debug) - log(LOG_DEBUG, SPP_FMT "lcp parse opt values: ", - SPP_ARGS(ifp)); - - p = (void*) (h+1); - len = origlen; - for (rlen=0; len >= 2 && p[1] >= 2 && len >= p[1]; - len-=p[1], p+=p[1]) { - if (debug) - log(-1, " %s ", sppp_lcp_opt_name(*p)); - switch (*p) { - case LCP_OPT_MAGIC: - /* Magic number -- extract. */ - nmagic = (u_long)p[2] << 24 | - (u_long)p[3] << 16 | p[4] << 8 | p[5]; - if (nmagic != sp->lcp.magic) { - sp->pp_loopcnt = 0; - if (debug) - log(-1, "0x%lx ", nmagic); - continue; - } - if (debug && sp->pp_loopcnt < MAXALIVECNT*5) - log(-1, "[glitch] "); - ++sp->pp_loopcnt; - /* - * We negate our magic here, and NAK it. If - * we see it later in an NAK packet, we - * suggest a new one. - */ - nmagic = ~sp->lcp.magic; - /* Gonna NAK it. */ - p[2] = nmagic >> 24; - p[3] = nmagic >> 16; - p[4] = nmagic >> 8; - p[5] = nmagic; - break; - - case LCP_OPT_ASYNC_MAP: - /* - * Async control character map -- just ignore it. - * - * Quote from RFC 1662, chapter 6: - * To enable this functionality, synchronous PPP - * implementations MUST always respond to the - * Async-Control-Character-Map Configuration - * Option with the LCP Configure-Ack. However, - * acceptance of the Configuration Option does - * not imply that the synchronous implementation - * will do any ACCM mapping. Instead, all such - * octet mapping will be performed by the - * asynchronous-to-synchronous converter. - */ - continue; - - case LCP_OPT_MRU: - /* - * Maximum receive unit. Always agreeable, - * but ignored by now. - */ - sp->lcp.their_mru = p[2] * 256 + p[3]; - if (debug) - log(-1, "%lu ", sp->lcp.their_mru); - continue; - - case LCP_OPT_AUTH_PROTO: - authproto = (p[2] << 8) + p[3]; - if (sp->myauth.proto != authproto) { - /* not agreed, nak */ - if (debug) - log(-1, "[mine %s != his %s] ", - sppp_proto_name(sp->hisauth.proto), - sppp_proto_name(authproto)); - p[2] = sp->myauth.proto >> 8; - p[3] = sp->myauth.proto; - break; - } - if (authproto == PPP_CHAP && p[4] != CHAP_MD5) { - if (debug) - log(-1, "[chap not MD5] "); - p[4] = CHAP_MD5; - break; - } - continue; - } - /* Add the option to nak'ed list. */ - bcopy (p, r, p[1]); - r += p[1]; - rlen += p[1]; - } - if (rlen) { - /* - * Local and remote magics equal -- loopback? - */ - if (sp->pp_loopcnt >= MAXALIVECNT*5) { - if (sp->pp_loopcnt == MAXALIVECNT*5) - printf (SPP_FMT "loopback\n", - SPP_ARGS(ifp)); - if (ifp->if_flags & IFF_UP) { - if_down(ifp); - sppp_qflush(&sp->pp_cpq); - /* XXX ? */ - lcp.Down(sp); - lcp.Up(sp); - } - } else if (!sp->pp_loopcnt && - ++sp->fail_counter[IDX_LCP] >= sp->lcp.max_failure) { - if (debug) - log(-1, " max_failure (%d) exceeded, " - "send conf-rej\n", - sp->lcp.max_failure); - sppp_cp_send(sp, PPP_LCP, CONF_REJ, h->ident, rlen, buf); - } else { - if (debug) - log(-1, " send conf-nak\n"); - sppp_cp_send (sp, PPP_LCP, CONF_NAK, h->ident, rlen, buf); - } - } else { - if (debug) - log(-1, " send conf-ack\n"); - sp->fail_counter[IDX_LCP] = 0; - sp->pp_loopcnt = 0; - sppp_cp_send (sp, PPP_LCP, CONF_ACK, - h->ident, origlen, h+1); - } - - free (buf, M_TEMP); - return (rlen == 0); -} - -/* - * Analyze the LCP Configure-Reject option list, and adjust our - * negotiation. - */ -static void -sppp_lcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) -{ - STDDCL; - u_char *buf, *p; - - len -= 4; - buf = malloc (len, M_TEMP, M_NOWAIT); - if (!buf) - return; - - if (debug) - log(LOG_DEBUG, SPP_FMT "lcp rej opts: ", - SPP_ARGS(ifp)); - - p = (void*) (h+1); - for (; len >= 2 && p[1] >= 2 && len >= p[1]; - len -= p[1], p += p[1]) { - if (debug) - log(-1, " %s ", sppp_lcp_opt_name(*p)); - switch (*p) { - case LCP_OPT_MAGIC: - /* Magic number -- can't use it, use 0 */ - sp->lcp.opts &= ~(1 << LCP_OPT_MAGIC); - sp->lcp.magic = 0; - break; - case LCP_OPT_MRU: - /* - * Should not be rejected anyway, since we only - * negotiate a MRU if explicitly requested by - * peer. - */ - sp->lcp.opts &= ~(1 << LCP_OPT_MRU); - break; - case LCP_OPT_AUTH_PROTO: - /* - * Peer doesn't want to authenticate himself, - * deny unless this is a dialout call, and - * AUTHFLAG_NOCALLOUT is set. - */ - if ((sp->pp_flags & PP_CALLIN) == 0 && - (sp->hisauth.flags & AUTHFLAG_NOCALLOUT) != 0) { - if (debug) - log(-1, "[don't insist on auth " - "for callout]"); - sp->lcp.opts &= ~(1 << LCP_OPT_AUTH_PROTO); - break; - } - if (debug) - log(-1, "[access denied]\n"); - lcp.Close(sp); - break; - } - } - if (debug) - log(-1, "\n"); - free (buf, M_TEMP); - return; -} - -/* - * Analyze the LCP Configure-NAK option list, and adjust our - * negotiation. - */ -static void -sppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) -{ - STDDCL; - u_char *buf, *p; - u_long magic; - - len -= 4; - buf = malloc (len, M_TEMP, M_NOWAIT); - if (!buf) - return; - - if (debug) - log(LOG_DEBUG, SPP_FMT "lcp nak opts: ", - SPP_ARGS(ifp)); - - p = (void*) (h+1); - for (; len >= 2 && p[1] >= 2 && len >= p[1]; - len -= p[1], p += p[1]) { - if (debug) - log(-1, " %s ", sppp_lcp_opt_name(*p)); - switch (*p) { - case LCP_OPT_MAGIC: - /* Magic number -- renegotiate */ - if ((sp->lcp.opts & (1 << LCP_OPT_MAGIC)) && - len >= 6 && p[1] == 6) { - magic = (u_long)p[2] << 24 | - (u_long)p[3] << 16 | p[4] << 8 | p[5]; - /* - * If the remote magic is our negated one, - * this looks like a loopback problem. - * Suggest a new magic to make sure. - */ - if (magic == ~sp->lcp.magic) { - if (debug) - log(-1, "magic glitch "); - sp->lcp.magic = random(); - } else { - sp->lcp.magic = magic; - if (debug) - log(-1, "%lu ", magic); - } - } - break; - case LCP_OPT_MRU: - /* - * Peer wants to advise us to negotiate an MRU. - * Agree on it if it's reasonable, or use - * default otherwise. - */ - if (len >= 4 && p[1] == 4) { - u_int mru = p[2] * 256 + p[3]; - if (debug) - log(-1, "%d ", mru); - if (mru < PP_MTU || mru > PP_MAX_MRU) - mru = PP_MTU; - sp->lcp.mru = mru; - sp->lcp.opts |= (1 << LCP_OPT_MRU); - } - break; - case LCP_OPT_AUTH_PROTO: - /* - * Peer doesn't like our authentication method, - * deny. - */ - if (debug) - log(-1, "[access denied]\n"); - lcp.Close(sp); - break; - } - } - if (debug) - log(-1, "\n"); - free (buf, M_TEMP); - return; -} - -static void -sppp_lcp_tlu(struct sppp *sp) -{ - STDDCL; - int i; - u_long mask; - - /* XXX ? */ - if (! (ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING)) { - /* Coming out of loopback mode. */ - if_up(ifp); - printf (SPP_FMT "up\n", SPP_ARGS(ifp)); - } - - for (i = 0; i < IDX_COUNT; i++) - if ((cps[i])->flags & CP_QUAL) - (cps[i])->Open(sp); - - if ((sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) != 0 || - (sp->pp_flags & PP_NEEDAUTH) != 0) - sp->pp_phase = PHASE_AUTHENTICATE; - else - sp->pp_phase = PHASE_NETWORK; - - if (debug) - log(LOG_DEBUG, SPP_FMT "phase %s\n", SPP_ARGS(ifp), - sppp_phase_name(sp->pp_phase)); - - /* - * Open all authentication protocols. This is even required - * if we already proceeded to network phase, since it might be - * that remote wants us to authenticate, so we might have to - * send a PAP request. Undesired authentication protocols - * don't do anything when they get an Open event. - */ - for (i = 0; i < IDX_COUNT; i++) - if ((cps[i])->flags & CP_AUTH) - (cps[i])->Open(sp); - - if (sp->pp_phase == PHASE_NETWORK) { - /* Notify all NCPs. */ - for (i = 0; i < IDX_COUNT; i++) - if (((cps[i])->flags & CP_NCP) && - /* - * XXX - * Hack to administratively disable IPv6 if - * not desired. Perhaps we should have another - * flag for this, but right now, we can make - * all struct cp's read/only. - */ - (cps[i] != &ipv6cp || - (sp->confflags & CONF_ENABLE_IPV6))) - (cps[i])->Open(sp); - } - - /* Send Up events to all started protos. */ - for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1) - if ((sp->lcp.protos & mask) && ((cps[i])->flags & CP_LCP) == 0) - (cps[i])->Up(sp); - - /* notify low-level driver of state change */ - if (sp->pp_chg) - sp->pp_chg(sp, (int)sp->pp_phase); - - if (sp->pp_phase == PHASE_NETWORK) - /* if no NCP is starting, close down */ - sppp_lcp_check_and_close(sp); -} - -static void -sppp_lcp_tld(struct sppp *sp) -{ - STDDCL; - int i; - u_long mask; - - sp->pp_phase = PHASE_TERMINATE; - - if (debug) - log(LOG_DEBUG, SPP_FMT "phase %s\n", SPP_ARGS(ifp), - sppp_phase_name(sp->pp_phase)); - - /* - * Take upper layers down. We send the Down event first and - * the Close second to prevent the upper layers from sending - * ``a flurry of terminate-request packets'', as the RFC - * describes it. - */ - for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1) - if ((sp->lcp.protos & mask) && ((cps[i])->flags & CP_LCP) == 0) { - (cps[i])->Down(sp); - (cps[i])->Close(sp); - } -} - -static void -sppp_lcp_tls(struct sppp *sp) -{ - STDDCL; - - sp->pp_phase = PHASE_ESTABLISH; - - if (debug) - log(LOG_DEBUG, SPP_FMT "phase %s\n", SPP_ARGS(ifp), - sppp_phase_name(sp->pp_phase)); - - /* Notify lower layer if desired. */ - if (sp->pp_tls) - (sp->pp_tls)(sp); - else - (sp->pp_up)(sp); -} - -static void -sppp_lcp_tlf(struct sppp *sp) -{ - STDDCL; - - sp->pp_phase = PHASE_DEAD; - if (debug) - log(LOG_DEBUG, SPP_FMT "phase %s\n", SPP_ARGS(ifp), - sppp_phase_name(sp->pp_phase)); - - /* Notify lower layer if desired. */ - if (sp->pp_tlf) - (sp->pp_tlf)(sp); - else - (sp->pp_down)(sp); -} - -static void -sppp_lcp_scr(struct sppp *sp) -{ - char opt[6 /* magicnum */ + 4 /* mru */ + 5 /* chap */]; - int i = 0; - u_short authproto; - - if (sp->lcp.opts & (1 << LCP_OPT_MAGIC)) { - if (! sp->lcp.magic) - sp->lcp.magic = random(); - opt[i++] = LCP_OPT_MAGIC; - opt[i++] = 6; - opt[i++] = sp->lcp.magic >> 24; - opt[i++] = sp->lcp.magic >> 16; - opt[i++] = sp->lcp.magic >> 8; - opt[i++] = sp->lcp.magic; - } - - if (sp->lcp.opts & (1 << LCP_OPT_MRU)) { - opt[i++] = LCP_OPT_MRU; - opt[i++] = 4; - opt[i++] = sp->lcp.mru >> 8; - opt[i++] = sp->lcp.mru; - } - - if (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) { - authproto = sp->hisauth.proto; - opt[i++] = LCP_OPT_AUTH_PROTO; - opt[i++] = authproto == PPP_CHAP? 5: 4; - opt[i++] = authproto >> 8; - opt[i++] = authproto; - if (authproto == PPP_CHAP) - opt[i++] = CHAP_MD5; - } - - sp->confid[IDX_LCP] = ++sp->pp_seq[IDX_LCP]; - sppp_cp_send (sp, PPP_LCP, CONF_REQ, sp->confid[IDX_LCP], i, &opt); -} - -/* - * Check the open NCPs, return true if at least one NCP is open. - */ -static int -sppp_ncp_check(struct sppp *sp) -{ - int i, mask; - - for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1) - if ((sp->lcp.protos & mask) && (cps[i])->flags & CP_NCP) - return 1; - return 0; -} - -/* - * Re-check the open NCPs and see if we should terminate the link. - * Called by the NCPs during their tlf action handling. - */ -static void -sppp_lcp_check_and_close(struct sppp *sp) -{ - - if (sp->pp_phase < PHASE_NETWORK) - /* don't bother, we are already going down */ - return; - - if (sppp_ncp_check(sp)) - return; - - lcp.Close(sp); -} - -/* - *--------------------------------------------------------------------------* - * * - * The IPCP implementation. * - * * - *--------------------------------------------------------------------------* - */ - -#ifdef INET -static void -sppp_ipcp_init(struct sppp *sp) -{ - sp->ipcp.opts = 0; - sp->ipcp.flags = 0; - sp->state[IDX_IPCP] = STATE_INITIAL; - sp->fail_counter[IDX_IPCP] = 0; - sp->pp_seq[IDX_IPCP] = 0; - sp->pp_rseq[IDX_IPCP] = 0; - callout_init(&sp->ch[IDX_IPCP], 1); -} - -static void -sppp_ipcp_up(struct sppp *sp) -{ - sppp_up_event(&ipcp, sp); -} - -static void -sppp_ipcp_down(struct sppp *sp) -{ - sppp_down_event(&ipcp, sp); -} - -static void -sppp_ipcp_open(struct sppp *sp) -{ - STDDCL; - u_long myaddr, hisaddr; - - sp->ipcp.flags &= ~(IPCP_HISADDR_SEEN | IPCP_MYADDR_SEEN | - IPCP_MYADDR_DYN | IPCP_VJ); - sp->ipcp.opts = 0; - - sppp_get_ip_addrs(sp, &myaddr, &hisaddr, 0); - /* - * If we don't have his address, this probably means our - * interface doesn't want to talk IP at all. (This could - * be the case if somebody wants to speak only IPX, for - * example.) Don't open IPCP in this case. - */ - if (hisaddr == 0L) { - /* XXX this message should go away */ - if (debug) - log(LOG_DEBUG, SPP_FMT "ipcp_open(): no IP interface\n", - SPP_ARGS(ifp)); - return; - } - if (myaddr == 0L) { - /* - * I don't have an assigned address, so i need to - * negotiate my address. - */ - sp->ipcp.flags |= IPCP_MYADDR_DYN; - sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS); - } else - sp->ipcp.flags |= IPCP_MYADDR_SEEN; - if (sp->confflags & CONF_ENABLE_VJ) { - sp->ipcp.opts |= (1 << IPCP_OPT_COMPRESSION); - sp->ipcp.max_state = MAX_STATES - 1; - sp->ipcp.compress_cid = 1; - } - sppp_open_event(&ipcp, sp); -} - -static void -sppp_ipcp_close(struct sppp *sp) -{ - sppp_close_event(&ipcp, sp); - if (sp->ipcp.flags & IPCP_MYADDR_DYN) - /* - * My address was dynamic, clear it again. - */ - sppp_set_ip_addr(sp, 0L); -} - -static void -sppp_ipcp_TO(void *cookie) -{ - sppp_to_event(&ipcp, (struct sppp *)cookie); -} - -/* - * Analyze a configure request. Return true if it was agreeable, and - * caused action sca, false if it has been rejected or nak'ed, and - * caused action scn. (The return value is used to make the state - * transition decision in the state automaton.) - */ -static int -sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len) -{ - u_char *buf, *r, *p; - struct ifnet *ifp = SP2IFP(sp); - int rlen, origlen, debug = ifp->if_flags & IFF_DEBUG; - u_long hisaddr, desiredaddr; - int gotmyaddr = 0; - int desiredcomp; - - len -= 4; - origlen = len; - /* - * Make sure to allocate a buf that can at least hold a - * conf-nak with an `address' option. We might need it below. - */ - buf = r = malloc ((len < 6? 6: len), M_TEMP, M_NOWAIT); - if (! buf) - return (0); - - /* pass 1: see if we can recognize them */ - if (debug) - log(LOG_DEBUG, SPP_FMT "ipcp parse opts: ", - SPP_ARGS(ifp)); - p = (void*) (h+1); - for (rlen=0; len >= 2 && p[1] >= 2 && len >= p[1]; - len-=p[1], p+=p[1]) { - if (debug) - log(-1, " %s ", sppp_ipcp_opt_name(*p)); - switch (*p) { - case IPCP_OPT_COMPRESSION: - if (!(sp->confflags & CONF_ENABLE_VJ)) { - /* VJ compression administratively disabled */ - if (debug) - log(-1, "[locally disabled] "); - break; - } - /* - * In theory, we should only conf-rej an - * option that is shorter than RFC 1618 - * requires (i.e. < 4), and should conf-nak - * anything else that is not VJ. However, - * since our algorithm always uses the - * original option to NAK it with new values, - * things would become more complicated. In - * practice, the only commonly implemented IP - * compression option is VJ anyway, so the - * difference is negligible. - */ - if (len >= 6 && p[1] == 6) { - /* - * correctly formed compression option - * that could be VJ compression - */ - continue; - } - if (debug) - log(-1, - "optlen %d [invalid/unsupported] ", - p[1]); - break; - case IPCP_OPT_ADDRESS: - if (len >= 6 && p[1] == 6) { - /* correctly formed address option */ - continue; - } - if (debug) - log(-1, "[invalid] "); - break; - default: - /* Others not supported. */ - if (debug) - log(-1, "[rej] "); - break; - } - /* Add the option to rejected list. */ - bcopy (p, r, p[1]); - r += p[1]; - rlen += p[1]; - } - if (rlen) { - if (debug) - log(-1, " send conf-rej\n"); - sppp_cp_send (sp, PPP_IPCP, CONF_REJ, h->ident, rlen, buf); - return 0; - } else if (debug) - log(-1, "\n"); - - /* pass 2: parse option values */ - sppp_get_ip_addrs(sp, 0, &hisaddr, 0); - if (debug) - log(LOG_DEBUG, SPP_FMT "ipcp parse opt values: ", - SPP_ARGS(ifp)); - p = (void*) (h+1); - len = origlen; - for (rlen=0; len >= 2 && p[1] >= 2 && len >= p[1]; - len-=p[1], p+=p[1]) { - if (debug) - log(-1, " %s ", sppp_ipcp_opt_name(*p)); - switch (*p) { - case IPCP_OPT_COMPRESSION: - desiredcomp = p[2] << 8 | p[3]; - /* We only support VJ */ - if (desiredcomp == IPCP_COMP_VJ) { - if (debug) - log(-1, "VJ [ack] "); - sp->ipcp.flags |= IPCP_VJ; - sl_compress_init(sp->pp_comp, p[4]); - sp->ipcp.max_state = p[4]; - sp->ipcp.compress_cid = p[5]; - continue; - } - if (debug) - log(-1, - "compproto %#04x [not supported] ", - desiredcomp); - p[2] = IPCP_COMP_VJ >> 8; - p[3] = IPCP_COMP_VJ; - p[4] = sp->ipcp.max_state; - p[5] = sp->ipcp.compress_cid; - break; - case IPCP_OPT_ADDRESS: - /* This is the address he wants in his end */ - desiredaddr = p[2] << 24 | p[3] << 16 | - p[4] << 8 | p[5]; - if (desiredaddr == hisaddr || - (hisaddr >= 1 && hisaddr <= 254 && desiredaddr != 0)) { - /* - * Peer's address is same as our value, - * or we have set it to 0.0.0.* to - * indicate that we do not really care, - * this is agreeable. Gonna conf-ack - * it. - */ - if (debug) - log(-1, "%s [ack] ", - sppp_dotted_quad(hisaddr)); - /* record that we've seen it already */ - sp->ipcp.flags |= IPCP_HISADDR_SEEN; - continue; - } - /* - * The address wasn't agreeable. This is either - * he sent us 0.0.0.0, asking to assign him an - * address, or he send us another address not - * matching our value. Either case, we gonna - * conf-nak it with our value. - * XXX: we should "rej" if hisaddr == 0 - */ - if (debug) { - if (desiredaddr == 0) - log(-1, "[addr requested] "); - else - log(-1, "%s [not agreed] ", - sppp_dotted_quad(desiredaddr)); - } - p[2] = hisaddr >> 24; - p[3] = hisaddr >> 16; - p[4] = hisaddr >> 8; - p[5] = hisaddr; - break; - } - /* Add the option to nak'ed list. */ - bcopy (p, r, p[1]); - r += p[1]; - rlen += p[1]; - } - - /* - * If we are about to conf-ack the request, but haven't seen - * his address so far, gonna conf-nak it instead, with the - * `address' option present and our idea of his address being - * filled in there, to request negotiation of both addresses. - * - * XXX This can result in an endless req - nak loop if peer - * doesn't want to send us his address. Q: What should we do - * about it? XXX A: implement the max-failure counter. - */ - if (rlen == 0 && !(sp->ipcp.flags & IPCP_HISADDR_SEEN) && !gotmyaddr) { - buf[0] = IPCP_OPT_ADDRESS; - buf[1] = 6; - buf[2] = hisaddr >> 24; - buf[3] = hisaddr >> 16; - buf[4] = hisaddr >> 8; - buf[5] = hisaddr; - rlen = 6; - if (debug) - log(-1, "still need hisaddr "); - } - - if (rlen) { - if (debug) - log(-1, " send conf-nak\n"); - sppp_cp_send (sp, PPP_IPCP, CONF_NAK, h->ident, rlen, buf); - } else { - if (debug) - log(-1, " send conf-ack\n"); - sppp_cp_send (sp, PPP_IPCP, CONF_ACK, - h->ident, origlen, h+1); - } - - free (buf, M_TEMP); - return (rlen == 0); -} - -/* - * Analyze the IPCP Configure-Reject option list, and adjust our - * negotiation. - */ -static void -sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) -{ - u_char *buf, *p; - struct ifnet *ifp = SP2IFP(sp); - int debug = ifp->if_flags & IFF_DEBUG; - - len -= 4; - buf = malloc (len, M_TEMP, M_NOWAIT); - if (!buf) - return; - - if (debug) - log(LOG_DEBUG, SPP_FMT "ipcp rej opts: ", - SPP_ARGS(ifp)); - - p = (void*) (h+1); - for (; len >= 2 && p[1] >= 2 && len >= p[1]; - len -= p[1], p += p[1]) { - if (debug) - log(-1, " %s ", sppp_ipcp_opt_name(*p)); - switch (*p) { - case IPCP_OPT_COMPRESSION: - sp->ipcp.opts &= ~(1 << IPCP_OPT_COMPRESSION); - break; - case IPCP_OPT_ADDRESS: - /* - * Peer doesn't grok address option. This is - * bad. XXX Should we better give up here? - * XXX We could try old "addresses" option... - */ - sp->ipcp.opts &= ~(1 << IPCP_OPT_ADDRESS); - break; - } - } - if (debug) - log(-1, "\n"); - free (buf, M_TEMP); - return; -} - -/* - * Analyze the IPCP Configure-NAK option list, and adjust our - * negotiation. - */ -static void -sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) -{ - u_char *buf, *p; - struct ifnet *ifp = SP2IFP(sp); - int debug = ifp->if_flags & IFF_DEBUG; - int desiredcomp; - u_long wantaddr; - - len -= 4; - buf = malloc (len, M_TEMP, M_NOWAIT); - if (!buf) - return; - - if (debug) - log(LOG_DEBUG, SPP_FMT "ipcp nak opts: ", - SPP_ARGS(ifp)); - - p = (void*) (h+1); - for (; len >= 2 && p[1] >= 2 && len >= p[1]; - len -= p[1], p += p[1]) { - if (debug) - log(-1, " %s ", sppp_ipcp_opt_name(*p)); - switch (*p) { - case IPCP_OPT_COMPRESSION: - if (len >= 6 && p[1] == 6) { - desiredcomp = p[2] << 8 | p[3]; - if (debug) - log(-1, "[wantcomp %#04x] ", - desiredcomp); - if (desiredcomp == IPCP_COMP_VJ) { - sl_compress_init(sp->pp_comp, p[4]); - sp->ipcp.max_state = p[4]; - sp->ipcp.compress_cid = p[5]; - if (debug) - log(-1, "[agree] "); - } else - sp->ipcp.opts &= - ~(1 << IPCP_OPT_COMPRESSION); - } - break; - case IPCP_OPT_ADDRESS: - /* - * Peer doesn't like our local IP address. See - * if we can do something for him. We'll drop - * him our address then. - */ - if (len >= 6 && p[1] == 6) { - wantaddr = p[2] << 24 | p[3] << 16 | - p[4] << 8 | p[5]; - sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS); - if (debug) - log(-1, "[wantaddr %s] ", - sppp_dotted_quad(wantaddr)); - /* - * When doing dynamic address assignment, - * we accept his offer. Otherwise, we - * ignore it and thus continue to negotiate - * our already existing value. - * XXX: Bogus, if he said no once, he'll - * just say no again, might as well die. - */ - if (sp->ipcp.flags & IPCP_MYADDR_DYN) { - sppp_set_ip_addr(sp, wantaddr); - if (debug) - log(-1, "[agree] "); - sp->ipcp.flags |= IPCP_MYADDR_SEEN; - } - } - break; - } - } - if (debug) - log(-1, "\n"); - free (buf, M_TEMP); - return; -} - -static void -sppp_ipcp_tlu(struct sppp *sp) -{ - /* we are up - notify isdn daemon */ - if (sp->pp_con) - sp->pp_con(sp); -} - -static void -sppp_ipcp_tld(struct sppp *sp) -{ -} - -static void -sppp_ipcp_tls(struct sppp *sp) -{ - /* indicate to LCP that it must stay alive */ - sp->lcp.protos |= (1 << IDX_IPCP); -} - -static void -sppp_ipcp_tlf(struct sppp *sp) -{ - /* we no longer need LCP */ - sp->lcp.protos &= ~(1 << IDX_IPCP); - sppp_lcp_check_and_close(sp); -} - -static void -sppp_ipcp_scr(struct sppp *sp) -{ - char opt[6 /* compression */ + 6 /* address */]; - u_long ouraddr; - int i = 0; - - if (sp->ipcp.opts & (1 << IPCP_OPT_COMPRESSION)) { - opt[i++] = IPCP_OPT_COMPRESSION; - opt[i++] = 6; - opt[i++] = IPCP_COMP_VJ >> 8; - opt[i++] = IPCP_COMP_VJ; - opt[i++] = sp->ipcp.max_state; - opt[i++] = sp->ipcp.compress_cid; - } - if (sp->ipcp.opts & (1 << IPCP_OPT_ADDRESS)) { - sppp_get_ip_addrs(sp, &ouraddr, 0, 0); - opt[i++] = IPCP_OPT_ADDRESS; - opt[i++] = 6; - opt[i++] = ouraddr >> 24; - opt[i++] = ouraddr >> 16; - opt[i++] = ouraddr >> 8; - opt[i++] = ouraddr; - } - - sp->confid[IDX_IPCP] = ++sp->pp_seq[IDX_IPCP]; - sppp_cp_send(sp, PPP_IPCP, CONF_REQ, sp->confid[IDX_IPCP], i, &opt); -} -#else /* !INET */ -static void -sppp_ipcp_init(struct sppp *sp) -{ -} - -static void -sppp_ipcp_up(struct sppp *sp) -{ -} - -static void -sppp_ipcp_down(struct sppp *sp) -{ -} - -static void -sppp_ipcp_open(struct sppp *sp) -{ -} - -static void -sppp_ipcp_close(struct sppp *sp) -{ -} - -static void -sppp_ipcp_TO(void *cookie) -{ -} - -static int -sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len) -{ - return (0); -} - -static void -sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) -{ -} - -static void -sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) -{ -} - -static void -sppp_ipcp_tlu(struct sppp *sp) -{ -} - -static void -sppp_ipcp_tld(struct sppp *sp) -{ -} - -static void -sppp_ipcp_tls(struct sppp *sp) -{ -} - -static void -sppp_ipcp_tlf(struct sppp *sp) -{ -} - -static void -sppp_ipcp_scr(struct sppp *sp) -{ -} -#endif - -/* - *--------------------------------------------------------------------------* - * * - * The IPv6CP implementation. * - * * - *--------------------------------------------------------------------------* - */ - -#ifdef INET6 -static void -sppp_ipv6cp_init(struct sppp *sp) -{ - sp->ipv6cp.opts = 0; - sp->ipv6cp.flags = 0; - sp->state[IDX_IPV6CP] = STATE_INITIAL; - sp->fail_counter[IDX_IPV6CP] = 0; - sp->pp_seq[IDX_IPV6CP] = 0; - sp->pp_rseq[IDX_IPV6CP] = 0; - callout_init(&sp->ch[IDX_IPV6CP], 1); -} - -static void -sppp_ipv6cp_up(struct sppp *sp) -{ - sppp_up_event(&ipv6cp, sp); -} - -static void -sppp_ipv6cp_down(struct sppp *sp) -{ - sppp_down_event(&ipv6cp, sp); -} - -static void -sppp_ipv6cp_open(struct sppp *sp) -{ - STDDCL; - struct in6_addr myaddr, hisaddr; - -#ifdef IPV6CP_MYIFID_DYN - sp->ipv6cp.flags &= ~(IPV6CP_MYIFID_SEEN|IPV6CP_MYIFID_DYN); -#else - sp->ipv6cp.flags &= ~IPV6CP_MYIFID_SEEN; -#endif - - sppp_get_ip6_addrs(sp, &myaddr, &hisaddr, 0); - /* - * If we don't have our address, this probably means our - * interface doesn't want to talk IPv6 at all. (This could - * be the case if somebody wants to speak only IPX, for - * example.) Don't open IPv6CP in this case. - */ - if (IN6_IS_ADDR_UNSPECIFIED(&myaddr)) { - /* XXX this message should go away */ - if (debug) - log(LOG_DEBUG, SPP_FMT "ipv6cp_open(): no IPv6 interface\n", - SPP_ARGS(ifp)); - return; - } - - sp->ipv6cp.flags |= IPV6CP_MYIFID_SEEN; - sp->ipv6cp.opts |= (1 << IPV6CP_OPT_IFID); - sppp_open_event(&ipv6cp, sp); -} - -static void -sppp_ipv6cp_close(struct sppp *sp) -{ - sppp_close_event(&ipv6cp, sp); -} - -static void -sppp_ipv6cp_TO(void *cookie) -{ - sppp_to_event(&ipv6cp, (struct sppp *)cookie); -} - -/* - * Analyze a configure request. Return true if it was agreeable, and - * caused action sca, false if it has been rejected or nak'ed, and - * caused action scn. (The return value is used to make the state - * transition decision in the state automaton.) - */ -static int -sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len) -{ - u_char *buf, *r, *p; - struct ifnet *ifp = SP2IFP(sp); - int rlen, origlen, debug = ifp->if_flags & IFF_DEBUG; - struct in6_addr myaddr, desiredaddr, suggestaddr; - int ifidcount; - int type; - int collision, nohisaddr; - char ip6buf[INET6_ADDRSTRLEN]; - - len -= 4; - origlen = len; - /* - * Make sure to allocate a buf that can at least hold a - * conf-nak with an `address' option. We might need it below. - */ - buf = r = malloc ((len < 6? 6: len), M_TEMP, M_NOWAIT); - if (! buf) - return (0); - - /* pass 1: see if we can recognize them */ - if (debug) - log(LOG_DEBUG, SPP_FMT "ipv6cp parse opts:", - SPP_ARGS(ifp)); - p = (void*) (h+1); - ifidcount = 0; - for (rlen=0; len >= 2 && p[1] >= 2 && len >= p[1]; - len-=p[1], p+=p[1]) { - if (debug) - log(-1, " %s", sppp_ipv6cp_opt_name(*p)); - switch (*p) { - case IPV6CP_OPT_IFID: - if (len >= 10 && p[1] == 10 && ifidcount == 0) { - /* correctly formed address option */ - ifidcount++; - continue; - } - if (debug) - log(-1, " [invalid]"); - break; -#ifdef notyet - case IPV6CP_OPT_COMPRESSION: - if (len >= 4 && p[1] >= 4) { - /* correctly formed compress option */ - continue; - } - if (debug) - log(-1, " [invalid]"); - break; -#endif - default: - /* Others not supported. */ - if (debug) - log(-1, " [rej]"); - break; - } - /* Add the option to rejected list. */ - bcopy (p, r, p[1]); - r += p[1]; - rlen += p[1]; - } - if (rlen) { - if (debug) - log(-1, " send conf-rej\n"); - sppp_cp_send (sp, PPP_IPV6CP, CONF_REJ, h->ident, rlen, buf); - goto end; - } else if (debug) - log(-1, "\n"); - - /* pass 2: parse option values */ - sppp_get_ip6_addrs(sp, &myaddr, 0, 0); - if (debug) - log(LOG_DEBUG, SPP_FMT "ipv6cp parse opt values: ", - SPP_ARGS(ifp)); - p = (void*) (h+1); - len = origlen; - type = CONF_ACK; - for (rlen=0; len >= 2 && p[1] >= 2 && len >= p[1]; - len-=p[1], p+=p[1]) { - if (debug) - log(-1, " %s", sppp_ipv6cp_opt_name(*p)); - switch (*p) { -#ifdef notyet - case IPV6CP_OPT_COMPRESSION: - continue; -#endif - case IPV6CP_OPT_IFID: - bzero(&desiredaddr, sizeof(desiredaddr)); - bcopy(&p[2], &desiredaddr.s6_addr[8], 8); - collision = (bcmp(&desiredaddr.s6_addr[8], - &myaddr.s6_addr[8], 8) == 0); - nohisaddr = IN6_IS_ADDR_UNSPECIFIED(&desiredaddr); - - desiredaddr.s6_addr16[0] = htons(0xfe80); - (void)in6_setscope(&desiredaddr, SP2IFP(sp), NULL); - - if (!collision && !nohisaddr) { - /* no collision, hisaddr known - Conf-Ack */ - type = CONF_ACK; - - if (debug) { - log(-1, " %s [%s]", - ip6_sprintf(ip6buf, &desiredaddr), - sppp_cp_type_name(type)); - } - continue; - } - - bzero(&suggestaddr, sizeof(suggestaddr)); - if (collision && nohisaddr) { - /* collision, hisaddr unknown - Conf-Rej */ - type = CONF_REJ; - bzero(&p[2], 8); - } else { - /* - * - no collision, hisaddr unknown, or - * - collision, hisaddr known - * Conf-Nak, suggest hisaddr - */ - type = CONF_NAK; - sppp_suggest_ip6_addr(sp, &suggestaddr); - bcopy(&suggestaddr.s6_addr[8], &p[2], 8); - } - if (debug) - log(-1, " %s [%s]", - ip6_sprintf(ip6buf, &desiredaddr), - sppp_cp_type_name(type)); - break; - } - /* Add the option to nak'ed list. */ - bcopy (p, r, p[1]); - r += p[1]; - rlen += p[1]; - } - - if (rlen == 0 && type == CONF_ACK) { - if (debug) - log(-1, " send %s\n", sppp_cp_type_name(type)); - sppp_cp_send (sp, PPP_IPV6CP, type, h->ident, origlen, h+1); - } else { -#ifdef DIAGNOSTIC - if (type == CONF_ACK) - panic("IPv6CP RCR: CONF_ACK with non-zero rlen"); -#endif - - if (debug) { - log(-1, " send %s suggest %s\n", - sppp_cp_type_name(type), - ip6_sprintf(ip6buf, &suggestaddr)); - } - sppp_cp_send (sp, PPP_IPV6CP, type, h->ident, rlen, buf); - } - - end: - free (buf, M_TEMP); - return (rlen == 0); -} - -/* - * Analyze the IPv6CP Configure-Reject option list, and adjust our - * negotiation. - */ -static void -sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) -{ - u_char *buf, *p; - struct ifnet *ifp = SP2IFP(sp); - int debug = ifp->if_flags & IFF_DEBUG; - - len -= 4; - buf = malloc (len, M_TEMP, M_NOWAIT); - if (!buf) - return; - - if (debug) - log(LOG_DEBUG, SPP_FMT "ipv6cp rej opts:", - SPP_ARGS(ifp)); - - p = (void*) (h+1); - for (; len >= 2 && p[1] >= 2 && len >= p[1]; - len -= p[1], p += p[1]) { - if (debug) - log(-1, " %s", sppp_ipv6cp_opt_name(*p)); - switch (*p) { - case IPV6CP_OPT_IFID: - /* - * Peer doesn't grok address option. This is - * bad. XXX Should we better give up here? - */ - sp->ipv6cp.opts &= ~(1 << IPV6CP_OPT_IFID); - break; -#ifdef notyet - case IPV6CP_OPT_COMPRESS: - sp->ipv6cp.opts &= ~(1 << IPV6CP_OPT_COMPRESS); - break; -#endif - } - } - if (debug) - log(-1, "\n"); - free (buf, M_TEMP); - return; -} - -/* - * Analyze the IPv6CP Configure-NAK option list, and adjust our - * negotiation. - */ -static void -sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) -{ - u_char *buf, *p; - struct ifnet *ifp = SP2IFP(sp); - int debug = ifp->if_flags & IFF_DEBUG; - struct in6_addr suggestaddr; - char ip6buf[INET6_ADDRSTRLEN]; - - len -= 4; - buf = malloc (len, M_TEMP, M_NOWAIT); - if (!buf) - return; - - if (debug) - log(LOG_DEBUG, SPP_FMT "ipv6cp nak opts:", - SPP_ARGS(ifp)); - - p = (void*) (h+1); - for (; len >= 2 && p[1] >= 2 && len >= p[1]; - len -= p[1], p += p[1]) { - if (debug) - log(-1, " %s", sppp_ipv6cp_opt_name(*p)); - switch (*p) { - case IPV6CP_OPT_IFID: - /* - * Peer doesn't like our local ifid. See - * if we can do something for him. We'll drop - * him our address then. - */ - if (len < 10 || p[1] != 10) - break; - bzero(&suggestaddr, sizeof(suggestaddr)); - suggestaddr.s6_addr16[0] = htons(0xfe80); - (void)in6_setscope(&suggestaddr, SP2IFP(sp), NULL); - bcopy(&p[2], &suggestaddr.s6_addr[8], 8); - - sp->ipv6cp.opts |= (1 << IPV6CP_OPT_IFID); - if (debug) - log(-1, " [suggestaddr %s]", - ip6_sprintf(ip6buf, &suggestaddr)); -#ifdef IPV6CP_MYIFID_DYN - /* - * When doing dynamic address assignment, - * we accept his offer. - */ - if (sp->ipv6cp.flags & IPV6CP_MYIFID_DYN) { - struct in6_addr lastsuggest; - /* - * If equals to - * , - * we have a collision. generate new random - * ifid. - */ - sppp_suggest_ip6_addr(&lastsuggest); - if (IN6_ARE_ADDR_EQUAL(&suggestaddr, - lastsuggest)) { - if (debug) - log(-1, " [random]"); - sppp_gen_ip6_addr(sp, &suggestaddr); - } - sppp_set_ip6_addr(sp, &suggestaddr, 0); - if (debug) - log(-1, " [agree]"); - sp->ipv6cp.flags |= IPV6CP_MYIFID_SEEN; - } -#else - /* - * Since we do not do dynamic address assignment, - * we ignore it and thus continue to negotiate - * our already existing value. This can possibly - * go into infinite request-reject loop. - * - * This is not likely because we normally use - * ifid based on MAC-address. - * If you have no ethernet card on the node, too bad. - * XXX should we use fail_counter? - */ -#endif - break; -#ifdef notyet - case IPV6CP_OPT_COMPRESS: - /* - * Peer wants different compression parameters. - */ - break; -#endif - } - } - if (debug) - log(-1, "\n"); - free (buf, M_TEMP); - return; -} -static void -sppp_ipv6cp_tlu(struct sppp *sp) -{ - /* we are up - notify isdn daemon */ - if (sp->pp_con) - sp->pp_con(sp); -} - -static void -sppp_ipv6cp_tld(struct sppp *sp) -{ -} - -static void -sppp_ipv6cp_tls(struct sppp *sp) -{ - /* indicate to LCP that it must stay alive */ - sp->lcp.protos |= (1 << IDX_IPV6CP); -} - -static void -sppp_ipv6cp_tlf(struct sppp *sp) -{ - -#if 0 /* need #if 0 to close IPv6CP properly */ - /* we no longer need LCP */ - sp->lcp.protos &= ~(1 << IDX_IPV6CP); - sppp_lcp_check_and_close(sp); -#endif -} - -static void -sppp_ipv6cp_scr(struct sppp *sp) -{ - char opt[10 /* ifid */ + 4 /* compression, minimum */]; - struct in6_addr ouraddr; - int i = 0; - - if (sp->ipv6cp.opts & (1 << IPV6CP_OPT_IFID)) { - sppp_get_ip6_addrs(sp, &ouraddr, 0, 0); - opt[i++] = IPV6CP_OPT_IFID; - opt[i++] = 10; - bcopy(&ouraddr.s6_addr[8], &opt[i], 8); - i += 8; - } - -#ifdef notyet - if (sp->ipv6cp.opts & (1 << IPV6CP_OPT_COMPRESSION)) { - opt[i++] = IPV6CP_OPT_COMPRESSION; - opt[i++] = 4; - opt[i++] = 0; /* TBD */ - opt[i++] = 0; /* TBD */ - /* variable length data may follow */ - } -#endif - - sp->confid[IDX_IPV6CP] = ++sp->pp_seq[IDX_IPV6CP]; - sppp_cp_send(sp, PPP_IPV6CP, CONF_REQ, sp->confid[IDX_IPV6CP], i, &opt); -} -#else /*INET6*/ -static void sppp_ipv6cp_init(struct sppp *sp) -{ -} - -static void sppp_ipv6cp_up(struct sppp *sp) -{ -} - -static void sppp_ipv6cp_down(struct sppp *sp) -{ -} - -static void sppp_ipv6cp_open(struct sppp *sp) -{ -} - -static void sppp_ipv6cp_close(struct sppp *sp) -{ -} - -static void sppp_ipv6cp_TO(void *sp) -{ -} - -static int sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len) -{ - return 0; -} - -static void sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) -{ -} - -static void sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) -{ -} - -static void sppp_ipv6cp_tlu(struct sppp *sp) -{ -} - -static void sppp_ipv6cp_tld(struct sppp *sp) -{ -} - -static void sppp_ipv6cp_tls(struct sppp *sp) -{ -} - -static void sppp_ipv6cp_tlf(struct sppp *sp) -{ -} - -static void sppp_ipv6cp_scr(struct sppp *sp) -{ -} -#endif /*INET6*/ - -/* - *--------------------------------------------------------------------------* - * * - * The CHAP implementation. * - * * - *--------------------------------------------------------------------------* - */ - -/* - * The authentication protocols don't employ a full-fledged state machine as - * the control protocols do, since they do have Open and Close events, but - * not Up and Down, nor are they explicitly terminated. Also, use of the - * authentication protocols may be different in both directions (this makes - * sense, think of a machine that never accepts incoming calls but only - * calls out, it doesn't require the called party to authenticate itself). - * - * Our state machine for the local authentication protocol (we are requesting - * the peer to authenticate) looks like: - * - * RCA- - * +--------------------------------------------+ - * V scn,tld| - * +--------+ Close +---------+ RCA+ - * | |<----------------------------------| |------+ - * +--->| Closed | TO* | Opened | sca | - * | | |-----+ +-------| |<-----+ - * | +--------+ irc | | +---------+ - * | ^ | | ^ - * | | | | | - * | | | | | - * | TO-| | | | - * | |tld TO+ V | | - * | | +------->+ | | - * | | | | | | - * | +--------+ V | | - * | | |<----+<--------------------+ | - * | | Req- | scr | - * | | Sent | | - * | | | | - * | +--------+ | - * | RCA- | | RCA+ | - * +------+ +------------------------------------------+ - * scn,tld sca,irc,ict,tlu - * - * - * with: - * - * Open: LCP reached authentication phase - * Close: LCP reached terminate phase - * - * RCA+: received reply (pap-req, chap-response), acceptable - * RCN: received reply (pap-req, chap-response), not acceptable - * TO+: timeout with restart counter >= 0 - * TO-: timeout with restart counter < 0 - * TO*: reschedule timeout for CHAP - * - * scr: send request packet (none for PAP, chap-challenge) - * sca: send ack packet (pap-ack, chap-success) - * scn: send nak packet (pap-nak, chap-failure) - * ict: initialize re-challenge timer (CHAP only) - * - * tlu: this-layer-up, LCP reaches network phase - * tld: this-layer-down, LCP enters terminate phase - * - * Note that in CHAP mode, after sending a new challenge, while the state - * automaton falls back into Req-Sent state, it doesn't signal a tld - * event to LCP, so LCP remains in network phase. Only after not getting - * any response (or after getting an unacceptable response), CHAP closes, - * causing LCP to enter terminate phase. - * - * With PAP, there is no initial request that can be sent. The peer is - * expected to send one based on the successful negotiation of PAP as - * the authentication protocol during the LCP option negotiation. - * - * Incoming authentication protocol requests (remote requests - * authentication, we are peer) don't employ a state machine at all, - * they are simply answered. Some peers [Ascend P50 firmware rev - * 4.50] react allergically when sending IPCP requests while they are - * still in authentication phase (thereby violating the standard that - * demands that these NCP packets are to be discarded), so we keep - * track of the peer demanding us to authenticate, and only proceed to - * phase network once we've seen a positive acknowledge for the - * authentication. - */ - -/* - * Handle incoming CHAP packets. - */ -static void -sppp_chap_input(struct sppp *sp, struct mbuf *m) -{ - STDDCL; - struct lcp_header *h; - int len; - u_char *value, *name, digest[AUTHKEYLEN], dsize; - int value_len, name_len; - MD5_CTX ctx; - - len = m->m_pkthdr.len; - if (len < 4) { - if (debug) - log(LOG_DEBUG, - SPP_FMT "chap invalid packet length: %d bytes\n", - SPP_ARGS(ifp), len); - return; - } - h = mtod (m, struct lcp_header*); - if (len > ntohs (h->len)) - len = ntohs (h->len); - - switch (h->type) { - /* challenge, failure and success are his authproto */ - case CHAP_CHALLENGE: - value = 1 + (u_char*)(h+1); - value_len = value[-1]; - name = value + value_len; - name_len = len - value_len - 5; - if (name_len < 0) { - if (debug) { - log(LOG_DEBUG, - SPP_FMT "chap corrupted challenge " - "<%s id=0x%x len=%d", - SPP_ARGS(ifp), - sppp_auth_type_name(PPP_CHAP, h->type), - h->ident, ntohs(h->len)); - sppp_print_bytes((u_char*) (h+1), len-4); - log(-1, ">\n"); - } - break; - } - - if (debug) { - log(LOG_DEBUG, - SPP_FMT "chap input <%s id=0x%x len=%d name=", - SPP_ARGS(ifp), - sppp_auth_type_name(PPP_CHAP, h->type), h->ident, - ntohs(h->len)); - sppp_print_string((char*) name, name_len); - log(-1, " value-size=%d value=", value_len); - sppp_print_bytes(value, value_len); - log(-1, ">\n"); - } - - /* Compute reply value. */ - MD5Init(&ctx); - MD5Update(&ctx, &h->ident, 1); - MD5Update(&ctx, sp->myauth.secret, - sppp_strnlen(sp->myauth.secret, AUTHKEYLEN)); - MD5Update(&ctx, value, value_len); - MD5Final(digest, &ctx); - dsize = sizeof digest; - - sppp_auth_send(&chap, sp, CHAP_RESPONSE, h->ident, - sizeof dsize, (const char *)&dsize, - sizeof digest, digest, - (size_t)sppp_strnlen(sp->myauth.name, AUTHNAMELEN), - sp->myauth.name, - 0); - break; - - case CHAP_SUCCESS: - if (debug) { - log(LOG_DEBUG, SPP_FMT "chap success", - SPP_ARGS(ifp)); - if (len > 4) { - log(-1, ": "); - sppp_print_string((char*)(h + 1), len - 4); - } - log(-1, "\n"); - } - SPPP_LOCK(sp); - sp->pp_flags &= ~PP_NEEDAUTH; - if (sp->myauth.proto == PPP_CHAP && - (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) && - (sp->lcp.protos & (1 << IDX_CHAP)) == 0) { - /* - * We are authenticator for CHAP but didn't - * complete yet. Leave it to tlu to proceed - * to network phase. - */ - SPPP_UNLOCK(sp); - break; - } - SPPP_UNLOCK(sp); - sppp_phase_network(sp); - break; - - case CHAP_FAILURE: - if (debug) { - log(LOG_INFO, SPP_FMT "chap failure", - SPP_ARGS(ifp)); - if (len > 4) { - log(-1, ": "); - sppp_print_string((char*)(h + 1), len - 4); - } - log(-1, "\n"); - } else - log(LOG_INFO, SPP_FMT "chap failure\n", - SPP_ARGS(ifp)); - /* await LCP shutdown by authenticator */ - break; - - /* response is my authproto */ - case CHAP_RESPONSE: - value = 1 + (u_char*)(h+1); - value_len = value[-1]; - name = value + value_len; - name_len = len - value_len - 5; - if (name_len < 0) { - if (debug) { - log(LOG_DEBUG, - SPP_FMT "chap corrupted response " - "<%s id=0x%x len=%d", - SPP_ARGS(ifp), - sppp_auth_type_name(PPP_CHAP, h->type), - h->ident, ntohs(h->len)); - sppp_print_bytes((u_char*)(h+1), len-4); - log(-1, ">\n"); - } - break; - } - if (h->ident != sp->confid[IDX_CHAP]) { - if (debug) - log(LOG_DEBUG, - SPP_FMT "chap dropping response for old ID " - "(got %d, expected %d)\n", - SPP_ARGS(ifp), - h->ident, sp->confid[IDX_CHAP]); - break; - } - if (name_len != sppp_strnlen(sp->hisauth.name, AUTHNAMELEN) - || bcmp(name, sp->hisauth.name, name_len) != 0) { - log(LOG_INFO, SPP_FMT "chap response, his name ", - SPP_ARGS(ifp)); - sppp_print_string(name, name_len); - log(-1, " != expected "); - sppp_print_string(sp->hisauth.name, - sppp_strnlen(sp->hisauth.name, AUTHNAMELEN)); - log(-1, "\n"); - } - if (debug) { - log(LOG_DEBUG, SPP_FMT "chap input(%s) " - "<%s id=0x%x len=%d name=", - SPP_ARGS(ifp), - sppp_state_name(sp->state[IDX_CHAP]), - sppp_auth_type_name(PPP_CHAP, h->type), - h->ident, ntohs (h->len)); - sppp_print_string((char*)name, name_len); - log(-1, " value-size=%d value=", value_len); - sppp_print_bytes(value, value_len); - log(-1, ">\n"); - } - if (value_len != AUTHKEYLEN) { - if (debug) - log(LOG_DEBUG, - SPP_FMT "chap bad hash value length: " - "%d bytes, should be %d\n", - SPP_ARGS(ifp), value_len, - AUTHKEYLEN); - break; - } - - MD5Init(&ctx); - MD5Update(&ctx, &h->ident, 1); - MD5Update(&ctx, sp->hisauth.secret, - sppp_strnlen(sp->hisauth.secret, AUTHKEYLEN)); - MD5Update(&ctx, sp->myauth.challenge, AUTHKEYLEN); - MD5Final(digest, &ctx); - -#define FAILMSG "Failed..." -#define SUCCMSG "Welcome!" - - if (value_len != sizeof digest || - bcmp(digest, value, value_len) != 0) { - /* action scn, tld */ - sppp_auth_send(&chap, sp, CHAP_FAILURE, h->ident, - sizeof(FAILMSG) - 1, (u_char *)FAILMSG, - 0); - chap.tld(sp); - break; - } - /* action sca, perhaps tlu */ - if (sp->state[IDX_CHAP] == STATE_REQ_SENT || - sp->state[IDX_CHAP] == STATE_OPENED) - sppp_auth_send(&chap, sp, CHAP_SUCCESS, h->ident, - sizeof(SUCCMSG) - 1, (u_char *)SUCCMSG, - 0); - if (sp->state[IDX_CHAP] == STATE_REQ_SENT) { - sppp_cp_change_state(&chap, sp, STATE_OPENED); - chap.tlu(sp); - } - break; - - default: - /* Unknown CHAP packet type -- ignore. */ - if (debug) { - log(LOG_DEBUG, SPP_FMT "chap unknown input(%s) " - "<0x%x id=0x%xh len=%d", - SPP_ARGS(ifp), - sppp_state_name(sp->state[IDX_CHAP]), - h->type, h->ident, ntohs(h->len)); - sppp_print_bytes((u_char*)(h+1), len-4); - log(-1, ">\n"); - } - break; - } -} - -static void -sppp_chap_init(struct sppp *sp) -{ - /* Chap doesn't have STATE_INITIAL at all. */ - sp->state[IDX_CHAP] = STATE_CLOSED; - sp->fail_counter[IDX_CHAP] = 0; - sp->pp_seq[IDX_CHAP] = 0; - sp->pp_rseq[IDX_CHAP] = 0; - callout_init(&sp->ch[IDX_CHAP], 1); -} - -static void -sppp_chap_open(struct sppp *sp) -{ - if (sp->myauth.proto == PPP_CHAP && - (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) != 0) { - /* we are authenticator for CHAP, start it */ - chap.scr(sp); - sp->rst_counter[IDX_CHAP] = sp->lcp.max_configure; - sppp_cp_change_state(&chap, sp, STATE_REQ_SENT); - } - /* nothing to be done if we are peer, await a challenge */ -} - -static void -sppp_chap_close(struct sppp *sp) -{ - if (sp->state[IDX_CHAP] != STATE_CLOSED) - sppp_cp_change_state(&chap, sp, STATE_CLOSED); -} - -static void -sppp_chap_TO(void *cookie) -{ - struct sppp *sp = (struct sppp *)cookie; - STDDCL; - - SPPP_LOCK(sp); - if (debug) - log(LOG_DEBUG, SPP_FMT "chap TO(%s) rst_counter = %d\n", - SPP_ARGS(ifp), - sppp_state_name(sp->state[IDX_CHAP]), - sp->rst_counter[IDX_CHAP]); - - if (--sp->rst_counter[IDX_CHAP] < 0) - /* TO- event */ - switch (sp->state[IDX_CHAP]) { - case STATE_REQ_SENT: - chap.tld(sp); - sppp_cp_change_state(&chap, sp, STATE_CLOSED); - break; - } - else - /* TO+ (or TO*) event */ - switch (sp->state[IDX_CHAP]) { - case STATE_OPENED: - /* TO* event */ - sp->rst_counter[IDX_CHAP] = sp->lcp.max_configure; - /* FALLTHROUGH */ - case STATE_REQ_SENT: - chap.scr(sp); - /* sppp_cp_change_state() will restart the timer */ - sppp_cp_change_state(&chap, sp, STATE_REQ_SENT); - break; - } - - SPPP_UNLOCK(sp); -} - -static void -sppp_chap_tlu(struct sppp *sp) -{ - STDDCL; - int i; - - i = 0; - sp->rst_counter[IDX_CHAP] = sp->lcp.max_configure; - - /* - * Some broken CHAP implementations (Conware CoNet, firmware - * 4.0.?) don't want to re-authenticate their CHAP once the - * initial challenge-response exchange has taken place. - * Provide for an option to avoid rechallenges. - */ - if ((sp->hisauth.flags & AUTHFLAG_NORECHALLENGE) == 0) { - /* - * Compute the re-challenge timeout. This will yield - * a number between 300 and 810 seconds. - */ - i = 300 + ((unsigned)(random() & 0xff00) >> 7); - callout_reset(&sp->ch[IDX_CHAP], i * hz, chap.TO, (void *)sp); - } - - if (debug) { - log(LOG_DEBUG, - SPP_FMT "chap %s, ", - SPP_ARGS(ifp), - sp->pp_phase == PHASE_NETWORK? "reconfirmed": "tlu"); - if ((sp->hisauth.flags & AUTHFLAG_NORECHALLENGE) == 0) - log(-1, "next re-challenge in %d seconds\n", i); - else - log(-1, "re-challenging suppressed\n"); - } - - SPPP_LOCK(sp); - /* indicate to LCP that we need to be closed down */ - sp->lcp.protos |= (1 << IDX_CHAP); - - if (sp->pp_flags & PP_NEEDAUTH) { - /* - * Remote is authenticator, but his auth proto didn't - * complete yet. Defer the transition to network - * phase. - */ - SPPP_UNLOCK(sp); - return; - } - SPPP_UNLOCK(sp); - - /* - * If we are already in phase network, we are done here. This - * is the case if this is a dummy tlu event after a re-challenge. - */ - if (sp->pp_phase != PHASE_NETWORK) - sppp_phase_network(sp); -} - -static void -sppp_chap_tld(struct sppp *sp) -{ - STDDCL; - - if (debug) - log(LOG_DEBUG, SPP_FMT "chap tld\n", SPP_ARGS(ifp)); - callout_stop(&sp->ch[IDX_CHAP]); - sp->lcp.protos &= ~(1 << IDX_CHAP); - - lcp.Close(sp); -} - -static void -sppp_chap_scr(struct sppp *sp) -{ - u_long *ch; - u_char clen; - - /* Compute random challenge. */ - ch = (u_long *)sp->myauth.challenge; - arc4random_buf(ch, 4 * sizeof(*ch)); - clen = AUTHKEYLEN; - - sp->confid[IDX_CHAP] = ++sp->pp_seq[IDX_CHAP]; - - sppp_auth_send(&chap, sp, CHAP_CHALLENGE, sp->confid[IDX_CHAP], - sizeof clen, (const char *)&clen, - (size_t)AUTHKEYLEN, sp->myauth.challenge, - (size_t)sppp_strnlen(sp->myauth.name, AUTHNAMELEN), - sp->myauth.name, - 0); -} - -/* - *--------------------------------------------------------------------------* - * * - * The PAP implementation. * - * * - *--------------------------------------------------------------------------* - */ -/* - * For PAP, we need to keep a little state also if we are the peer, not the - * authenticator. This is since we don't get a request to authenticate, but - * have to repeatedly authenticate ourself until we got a response (or the - * retry counter is expired). - */ - -/* - * Handle incoming PAP packets. */ -static void -sppp_pap_input(struct sppp *sp, struct mbuf *m) -{ - STDDCL; - struct lcp_header *h; - int len; - u_char *name, *passwd, mlen; - int name_len, passwd_len; - - len = m->m_pkthdr.len; - if (len < 5) { - if (debug) - log(LOG_DEBUG, - SPP_FMT "pap invalid packet length: %d bytes\n", - SPP_ARGS(ifp), len); - return; - } - h = mtod (m, struct lcp_header*); - if (len > ntohs (h->len)) - len = ntohs (h->len); - switch (h->type) { - /* PAP request is my authproto */ - case PAP_REQ: - name = 1 + (u_char*)(h+1); - name_len = name[-1]; - passwd = name + name_len + 1; - if (name_len > len - 6 || - (passwd_len = passwd[-1]) > len - 6 - name_len) { - if (debug) { - log(LOG_DEBUG, SPP_FMT "pap corrupted input " - "<%s id=0x%x len=%d", - SPP_ARGS(ifp), - sppp_auth_type_name(PPP_PAP, h->type), - h->ident, ntohs(h->len)); - sppp_print_bytes((u_char*)(h+1), len-4); - log(-1, ">\n"); - } - break; - } - if (debug) { - log(LOG_DEBUG, SPP_FMT "pap input(%s) " - "<%s id=0x%x len=%d name=", - SPP_ARGS(ifp), - sppp_state_name(sp->state[IDX_PAP]), - sppp_auth_type_name(PPP_PAP, h->type), - h->ident, ntohs(h->len)); - sppp_print_string((char*)name, name_len); - log(-1, " passwd="); - sppp_print_string((char*)passwd, passwd_len); - log(-1, ">\n"); - } - if (name_len != sppp_strnlen(sp->hisauth.name, AUTHNAMELEN) || - passwd_len != sppp_strnlen(sp->hisauth.secret, AUTHKEYLEN) || - bcmp(name, sp->hisauth.name, name_len) != 0 || - bcmp(passwd, sp->hisauth.secret, passwd_len) != 0) { - /* action scn, tld */ - mlen = sizeof(FAILMSG) - 1; - sppp_auth_send(&pap, sp, PAP_NAK, h->ident, - sizeof mlen, (const char *)&mlen, - sizeof(FAILMSG) - 1, (u_char *)FAILMSG, - 0); - pap.tld(sp); - break; - } - /* action sca, perhaps tlu */ - if (sp->state[IDX_PAP] == STATE_REQ_SENT || - sp->state[IDX_PAP] == STATE_OPENED) { - mlen = sizeof(SUCCMSG) - 1; - sppp_auth_send(&pap, sp, PAP_ACK, h->ident, - sizeof mlen, (const char *)&mlen, - sizeof(SUCCMSG) - 1, (u_char *)SUCCMSG, - 0); - } - if (sp->state[IDX_PAP] == STATE_REQ_SENT) { - sppp_cp_change_state(&pap, sp, STATE_OPENED); - pap.tlu(sp); - } - break; - - /* ack and nak are his authproto */ - case PAP_ACK: - callout_stop(&sp->pap_my_to_ch); - if (debug) { - log(LOG_DEBUG, SPP_FMT "pap success", - SPP_ARGS(ifp)); - name_len = *((char *)h); - if (len > 5 && name_len) { - log(-1, ": "); - sppp_print_string((char*)(h+1), name_len); - } - log(-1, "\n"); - } - SPPP_LOCK(sp); - sp->pp_flags &= ~PP_NEEDAUTH; - if (sp->myauth.proto == PPP_PAP && - (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) && - (sp->lcp.protos & (1 << IDX_PAP)) == 0) { - /* - * We are authenticator for PAP but didn't - * complete yet. Leave it to tlu to proceed - * to network phase. - */ - SPPP_UNLOCK(sp); - break; - } - SPPP_UNLOCK(sp); - sppp_phase_network(sp); - break; - - case PAP_NAK: - callout_stop (&sp->pap_my_to_ch); - if (debug) { - log(LOG_INFO, SPP_FMT "pap failure", - SPP_ARGS(ifp)); - name_len = *((char *)h); - if (len > 5 && name_len) { - log(-1, ": "); - sppp_print_string((char*)(h+1), name_len); - } - log(-1, "\n"); - } else - log(LOG_INFO, SPP_FMT "pap failure\n", - SPP_ARGS(ifp)); - /* await LCP shutdown by authenticator */ - break; - - default: - /* Unknown PAP packet type -- ignore. */ - if (debug) { - log(LOG_DEBUG, SPP_FMT "pap corrupted input " - "<0x%x id=0x%x len=%d", - SPP_ARGS(ifp), - h->type, h->ident, ntohs(h->len)); - sppp_print_bytes((u_char*)(h+1), len-4); - log(-1, ">\n"); - } - break; - } -} - -static void -sppp_pap_init(struct sppp *sp) -{ - /* PAP doesn't have STATE_INITIAL at all. */ - sp->state[IDX_PAP] = STATE_CLOSED; - sp->fail_counter[IDX_PAP] = 0; - sp->pp_seq[IDX_PAP] = 0; - sp->pp_rseq[IDX_PAP] = 0; - callout_init(&sp->ch[IDX_PAP], 1); - callout_init(&sp->pap_my_to_ch, 1); -} - -static void -sppp_pap_open(struct sppp *sp) -{ - if (sp->hisauth.proto == PPP_PAP && - (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) != 0) { - /* we are authenticator for PAP, start our timer */ - sp->rst_counter[IDX_PAP] = sp->lcp.max_configure; - sppp_cp_change_state(&pap, sp, STATE_REQ_SENT); - } - if (sp->myauth.proto == PPP_PAP) { - /* we are peer, send a request, and start a timer */ - pap.scr(sp); - callout_reset(&sp->pap_my_to_ch, sp->lcp.timeout, - sppp_pap_my_TO, (void *)sp); - } -} - -static void -sppp_pap_close(struct sppp *sp) -{ - if (sp->state[IDX_PAP] != STATE_CLOSED) - sppp_cp_change_state(&pap, sp, STATE_CLOSED); -} - -/* - * That's the timeout routine if we are authenticator. Since the - * authenticator is basically passive in PAP, we can't do much here. - */ -static void -sppp_pap_TO(void *cookie) -{ - struct sppp *sp = (struct sppp *)cookie; - STDDCL; - - SPPP_LOCK(sp); - if (debug) - log(LOG_DEBUG, SPP_FMT "pap TO(%s) rst_counter = %d\n", - SPP_ARGS(ifp), - sppp_state_name(sp->state[IDX_PAP]), - sp->rst_counter[IDX_PAP]); - - if (--sp->rst_counter[IDX_PAP] < 0) - /* TO- event */ - switch (sp->state[IDX_PAP]) { - case STATE_REQ_SENT: - pap.tld(sp); - sppp_cp_change_state(&pap, sp, STATE_CLOSED); - break; - } - else - /* TO+ event, not very much we could do */ - switch (sp->state[IDX_PAP]) { - case STATE_REQ_SENT: - /* sppp_cp_change_state() will restart the timer */ - sppp_cp_change_state(&pap, sp, STATE_REQ_SENT); - break; - } - - SPPP_UNLOCK(sp); -} - -/* - * That's the timeout handler if we are peer. Since the peer is active, - * we need to retransmit our PAP request since it is apparently lost. - * XXX We should impose a max counter. - */ -static void -sppp_pap_my_TO(void *cookie) -{ - struct sppp *sp = (struct sppp *)cookie; - STDDCL; - - if (debug) - log(LOG_DEBUG, SPP_FMT "pap peer TO\n", - SPP_ARGS(ifp)); - - SPPP_LOCK(sp); - pap.scr(sp); - SPPP_UNLOCK(sp); -} - -static void -sppp_pap_tlu(struct sppp *sp) -{ - STDDCL; - - sp->rst_counter[IDX_PAP] = sp->lcp.max_configure; - - if (debug) - log(LOG_DEBUG, SPP_FMT "%s tlu\n", - SPP_ARGS(ifp), pap.name); - - SPPP_LOCK(sp); - /* indicate to LCP that we need to be closed down */ - sp->lcp.protos |= (1 << IDX_PAP); - - if (sp->pp_flags & PP_NEEDAUTH) { - /* - * Remote is authenticator, but his auth proto didn't - * complete yet. Defer the transition to network - * phase. - */ - SPPP_UNLOCK(sp); - return; - } - SPPP_UNLOCK(sp); - sppp_phase_network(sp); -} - -static void -sppp_pap_tld(struct sppp *sp) -{ - STDDCL; - - if (debug) - log(LOG_DEBUG, SPP_FMT "pap tld\n", SPP_ARGS(ifp)); - callout_stop (&sp->ch[IDX_PAP]); - callout_stop (&sp->pap_my_to_ch); - sp->lcp.protos &= ~(1 << IDX_PAP); - - lcp.Close(sp); -} - -static void -sppp_pap_scr(struct sppp *sp) -{ - u_char idlen, pwdlen; - - sp->confid[IDX_PAP] = ++sp->pp_seq[IDX_PAP]; - pwdlen = sppp_strnlen(sp->myauth.secret, AUTHKEYLEN); - idlen = sppp_strnlen(sp->myauth.name, AUTHNAMELEN); - - sppp_auth_send(&pap, sp, PAP_REQ, sp->confid[IDX_PAP], - sizeof idlen, (const char *)&idlen, - (size_t)idlen, sp->myauth.name, - sizeof pwdlen, (const char *)&pwdlen, - (size_t)pwdlen, sp->myauth.secret, - 0); -} - -/* - * Random miscellaneous functions. - */ - -/* - * Send a PAP or CHAP proto packet. - * - * Varadic function, each of the elements for the ellipsis is of type - * ``size_t mlen, const u_char *msg''. Processing will stop iff - * mlen == 0. - * NOTE: never declare variadic functions with types subject to type - * promotion (i.e. u_char). This is asking for big trouble depending - * on the architecture you are on... - */ - -static void -sppp_auth_send(const struct cp *cp, struct sppp *sp, - unsigned int type, unsigned int id, - ...) -{ - STDDCL; - struct ppp_header *h; - struct lcp_header *lh; - struct mbuf *m; - u_char *p; - int len; - unsigned int mlen; - const char *msg; - va_list ap; - - MGETHDR (m, M_NOWAIT, MT_DATA); - if (! m) - return; - m->m_pkthdr.rcvif = 0; - - h = mtod (m, struct ppp_header*); - h->address = PPP_ALLSTATIONS; /* broadcast address */ - h->control = PPP_UI; /* Unnumbered Info */ - h->protocol = htons(cp->proto); - - lh = (struct lcp_header*)(h + 1); - lh->type = type; - lh->ident = id; - p = (u_char*) (lh+1); - - va_start(ap, id); - len = 0; - - while ((mlen = (unsigned int)va_arg(ap, size_t)) != 0) { - msg = va_arg(ap, const char *); - len += mlen; - if (len > MHLEN - PPP_HEADER_LEN - LCP_HEADER_LEN) { - va_end(ap); - m_freem(m); - return; - } - - bcopy(msg, p, mlen); - p += mlen; - } - va_end(ap); - - m->m_pkthdr.len = m->m_len = PPP_HEADER_LEN + LCP_HEADER_LEN + len; - lh->len = htons (LCP_HEADER_LEN + len); - - if (debug) { - log(LOG_DEBUG, SPP_FMT "%s output <%s id=0x%x len=%d", - SPP_ARGS(ifp), cp->name, - sppp_auth_type_name(cp->proto, lh->type), - lh->ident, ntohs(lh->len)); - sppp_print_bytes((u_char*) (lh+1), len); - log(-1, ">\n"); - } - if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3)) - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); -} - -/* - * Flush interface queue. - */ -static void -sppp_qflush(struct ifqueue *ifq) -{ - struct mbuf *m, *n; - - n = ifq->ifq_head; - while ((m = n)) { - n = m->m_nextpkt; - m_freem (m); - } - ifq->ifq_head = 0; - ifq->ifq_tail = 0; - ifq->ifq_len = 0; -} - -/* - * Send keepalive packets, every 10 seconds. - */ -static void -sppp_keepalive(void *dummy) -{ - struct sppp *sp = (struct sppp*)dummy; - struct ifnet *ifp = SP2IFP(sp); - - SPPP_LOCK(sp); - /* Keepalive mode disabled or channel down? */ - if (! (sp->pp_flags & PP_KEEPALIVE) || - ! (ifp->if_drv_flags & IFF_DRV_RUNNING)) - goto out; - - if (sp->pp_mode == PP_FR) { - sppp_fr_keepalive (sp); - goto out; - } - - /* No keepalive in PPP mode if LCP not opened yet. */ - if (sp->pp_mode != IFF_CISCO && - sp->pp_phase < PHASE_AUTHENTICATE) - goto out; - - if (sp->pp_alivecnt == MAXALIVECNT) { - /* No keepalive packets got. Stop the interface. */ - printf (SPP_FMT "down\n", SPP_ARGS(ifp)); - if_down (ifp); - sppp_qflush (&sp->pp_cpq); - if (sp->pp_mode != IFF_CISCO) { - /* XXX */ - /* Shut down the PPP link. */ - lcp.Down(sp); - /* Initiate negotiation. XXX */ - lcp.Up(sp); - } - } - if (sp->pp_alivecnt <= MAXALIVECNT) - ++sp->pp_alivecnt; - if (sp->pp_mode == IFF_CISCO) - sppp_cisco_send (sp, CISCO_KEEPALIVE_REQ, - ++sp->pp_seq[IDX_LCP], sp->pp_rseq[IDX_LCP]); - else if (sp->pp_phase >= PHASE_AUTHENTICATE) { - uint32_t nmagic = htonl(sp->lcp.magic); - sp->lcp.echoid = ++sp->pp_seq[IDX_LCP]; - sppp_cp_send (sp, PPP_LCP, ECHO_REQ, - sp->lcp.echoid, 4, &nmagic); - } -out: - SPPP_UNLOCK(sp); - callout_reset(&sp->keepalive_callout, hz * 10, sppp_keepalive, - (void *)sp); -} - -/* - * Get both IP addresses. - */ -void -sppp_get_ip_addrs(struct sppp *sp, u_long *src, u_long *dst, u_long *srcmask) -{ - struct epoch_tracker et; - struct ifnet *ifp = SP2IFP(sp); - struct ifaddr *ifa; - struct sockaddr_in *si, *sm; - u_long ssrc, ddst; - - sm = NULL; - ssrc = ddst = 0L; - /* - * Pick the first AF_INET address from the list, - * aliases don't make any sense on a p2p link anyway. - */ - si = NULL; - NET_EPOCH_ENTER(et); - CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) - if (ifa->ifa_addr->sa_family == AF_INET) { - si = (struct sockaddr_in *)ifa->ifa_addr; - sm = (struct sockaddr_in *)ifa->ifa_netmask; - if (si) - break; - } - if (ifa) { - if (si && si->sin_addr.s_addr) { - ssrc = si->sin_addr.s_addr; - if (srcmask) - *srcmask = ntohl(sm->sin_addr.s_addr); - } - - si = (struct sockaddr_in *)ifa->ifa_dstaddr; - if (si && si->sin_addr.s_addr) - ddst = si->sin_addr.s_addr; - } - NET_EPOCH_EXIT(et); - - if (dst) *dst = ntohl(ddst); - if (src) *src = ntohl(ssrc); -} - -#ifdef INET -/* - * Set my IP address. - */ -static void -sppp_set_ip_addr(struct sppp *sp, u_long src) -{ - STDDCL; - struct epoch_tracker et; - struct ifaddr *ifa; - struct sockaddr_in *si; - struct in_ifaddr *ia; - - /* - * Pick the first AF_INET address from the list, - * aliases don't make any sense on a p2p link anyway. - */ - si = NULL; - NET_EPOCH_ENTER(et); - CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - if (ifa->ifa_addr->sa_family == AF_INET) { - si = (struct sockaddr_in *)ifa->ifa_addr; - if (si != NULL) { - ifa_ref(ifa); - break; - } - } - } - NET_EPOCH_EXIT(et); - - if (ifa != NULL) { - int error; - int fibnum = ifp->if_fib; - - rt_addrmsg(RTM_DELETE, ifa, fibnum); - /* delete old route */ - ia = ifatoia(ifa); - error = in_handle_ifaddr_route(RTM_DELETE, ia); - if (debug && error) { - log(LOG_DEBUG, SPP_FMT "sppp_set_ip_addr: rtinit DEL failed, error=%d\n", - SPP_ARGS(ifp), error); - } - - /* set new address */ - si->sin_addr.s_addr = htonl(src); - IN_IFADDR_WLOCK(); - LIST_REMOVE(ia, ia_hash); - LIST_INSERT_HEAD(INADDR_HASH(si->sin_addr.s_addr), ia, ia_hash); - IN_IFADDR_WUNLOCK(); - - rt_addrmsg(RTM_ADD, ifa, fibnum); - /* add new route */ - error = in_handle_ifaddr_route(RTM_ADD, ia); - if (debug && error) { - log(LOG_DEBUG, SPP_FMT "sppp_set_ip_addr: rtinit ADD failed, error=%d", - SPP_ARGS(ifp), error); - } - ifa_free(ifa); - } -} -#endif - -#ifdef INET6 -/* - * Get both IPv6 addresses. - */ -static void -sppp_get_ip6_addrs(struct sppp *sp, struct in6_addr *src, struct in6_addr *dst, - struct in6_addr *srcmask) -{ - struct epoch_tracker et; - struct ifnet *ifp = SP2IFP(sp); - struct ifaddr *ifa; - struct sockaddr_in6 *si, *sm; - struct in6_addr ssrc, ddst; - - sm = NULL; - bzero(&ssrc, sizeof(ssrc)); - bzero(&ddst, sizeof(ddst)); - /* - * Pick the first link-local AF_INET6 address from the list, - * aliases don't make any sense on a p2p link anyway. - */ - si = NULL; - NET_EPOCH_ENTER(et); - CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) - if (ifa->ifa_addr->sa_family == AF_INET6) { - si = (struct sockaddr_in6 *)ifa->ifa_addr; - sm = (struct sockaddr_in6 *)ifa->ifa_netmask; - if (si && IN6_IS_ADDR_LINKLOCAL(&si->sin6_addr)) - break; - } - if (ifa) { - if (si && !IN6_IS_ADDR_UNSPECIFIED(&si->sin6_addr)) { - bcopy(&si->sin6_addr, &ssrc, sizeof(ssrc)); - if (srcmask) { - bcopy(&sm->sin6_addr, srcmask, - sizeof(*srcmask)); - } - } - - si = (struct sockaddr_in6 *)ifa->ifa_dstaddr; - if (si && !IN6_IS_ADDR_UNSPECIFIED(&si->sin6_addr)) - bcopy(&si->sin6_addr, &ddst, sizeof(ddst)); - } - - if (dst) - bcopy(&ddst, dst, sizeof(*dst)); - if (src) - bcopy(&ssrc, src, sizeof(*src)); - NET_EPOCH_EXIT(et); -} - -#ifdef IPV6CP_MYIFID_DYN -/* - * Generate random ifid. - */ -static void -sppp_gen_ip6_addr(struct sppp *sp, struct in6_addr *addr) -{ - /* TBD */ -} - -/* - * Set my IPv6 address. - */ -static void -sppp_set_ip6_addr(struct sppp *sp, const struct in6_addr *src) -{ - STDDCL; - struct epoch_tracker et; - struct ifaddr *ifa; - struct sockaddr_in6 *sin6; - - /* - * Pick the first link-local AF_INET6 address from the list, - * aliases don't make any sense on a p2p link anyway. - */ - - sin6 = NULL; - NET_EPOCH_ENTER(et); - CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - if (ifa->ifa_addr->sa_family == AF_INET6) { - sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; - if (sin6 && IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { - ifa_ref(ifa); - break; - } - } - } - NET_EPOCH_EXIT(et); - - if (ifa != NULL) { - int error; - struct sockaddr_in6 new_sin6 = *sin6; - - bcopy(src, &new_sin6.sin6_addr, sizeof(new_sin6.sin6_addr)); - error = in6_ifinit(ifp, ifatoia6(ifa), &new_sin6, 1); - if (debug && error) { - log(LOG_DEBUG, SPP_FMT "sppp_set_ip6_addr: in6_ifinit " - " failed, error=%d\n", SPP_ARGS(ifp), error); - } - ifa_free(ifa); - } -} -#endif - -/* - * Suggest a candidate address to be used by peer. - */ -static void -sppp_suggest_ip6_addr(struct sppp *sp, struct in6_addr *suggest) -{ - struct in6_addr myaddr; - struct timeval tv; - - sppp_get_ip6_addrs(sp, &myaddr, 0, 0); - - myaddr.s6_addr[8] &= ~0x02; /* u bit to "local" */ - microtime(&tv); - if ((tv.tv_usec & 0xff) == 0 && (tv.tv_sec & 0xff) == 0) { - myaddr.s6_addr[14] ^= 0xff; - myaddr.s6_addr[15] ^= 0xff; - } else { - myaddr.s6_addr[14] ^= (tv.tv_usec & 0xff); - myaddr.s6_addr[15] ^= (tv.tv_sec & 0xff); - } - if (suggest) - bcopy(&myaddr, suggest, sizeof(myaddr)); -} -#endif /*INET6*/ - -static int -sppp_params(struct sppp *sp, u_long cmd, void *data) -{ - u_long subcmd; - struct ifreq *ifr = (struct ifreq *)data; - struct spppreq *spr; - int rv = 0; - - if ((spr = malloc(sizeof(struct spppreq), M_TEMP, M_NOWAIT)) == NULL) - return (EAGAIN); - /* - * ifr_data_get_ptr(ifr) is supposed to point to a struct spppreq. - * Check the cmd word first before attempting to fetch all the - * data. - */ - rv = fueword(ifr_data_get_ptr(ifr), &subcmd); - if (rv == -1) { - rv = EFAULT; - goto quit; - } - - if (copyin(ifr_data_get_ptr(ifr), spr, sizeof(struct spppreq)) != 0) { - rv = EFAULT; - goto quit; - } - - switch (subcmd) { - case (u_long)SPPPIOGDEFS: - if (cmd != SIOCGIFGENERIC) { - rv = EINVAL; - break; - } - /* - * We copy over the entire current state, but clean - * out some of the stuff we don't wanna pass up. - * Remember, SIOCGIFGENERIC is unprotected, and can be - * called by any user. No need to ever get PAP or - * CHAP secrets back to userland anyway. - */ - spr->defs.pp_phase = sp->pp_phase; - spr->defs.enable_vj = (sp->confflags & CONF_ENABLE_VJ) != 0; - spr->defs.enable_ipv6 = (sp->confflags & CONF_ENABLE_IPV6) != 0; - spr->defs.lcp = sp->lcp; - spr->defs.ipcp = sp->ipcp; - spr->defs.ipv6cp = sp->ipv6cp; - spr->defs.myauth = sp->myauth; - spr->defs.hisauth = sp->hisauth; - bzero(spr->defs.myauth.secret, AUTHKEYLEN); - bzero(spr->defs.myauth.challenge, AUTHKEYLEN); - bzero(spr->defs.hisauth.secret, AUTHKEYLEN); - bzero(spr->defs.hisauth.challenge, AUTHKEYLEN); - /* - * Fixup the LCP timeout value to milliseconds so - * spppcontrol doesn't need to bother about the value - * of "hz". We do the reverse calculation below when - * setting it. - */ - spr->defs.lcp.timeout = sp->lcp.timeout * 1000 / hz; - rv = copyout(spr, ifr_data_get_ptr(ifr), - sizeof(struct spppreq)); - break; - - case (u_long)SPPPIOSDEFS: - if (cmd != SIOCSIFGENERIC) { - rv = EINVAL; - break; - } - /* - * We have a very specific idea of which fields we - * allow being passed back from userland, so to not - * clobber our current state. For one, we only allow - * setting anything if LCP is in dead or establish - * phase. Once the authentication negotiations - * started, the authentication settings must not be - * changed again. (The administrator can force an - * ifconfig down in order to get LCP back into dead - * phase.) - * - * Also, we only allow for authentication parameters to be - * specified. - * - * XXX Should allow to set or clear pp_flags. - * - * Finally, if the respective authentication protocol to - * be used is set differently than 0, but the secret is - * passed as all zeros, we don't trash the existing secret. - * This allows an administrator to change the system name - * only without clobbering the secret (which he didn't get - * back in a previous SPPPIOGDEFS call). However, the - * secrets are cleared if the authentication protocol is - * reset to 0. */ - if (sp->pp_phase != PHASE_DEAD && - sp->pp_phase != PHASE_ESTABLISH) { - rv = EBUSY; - break; - } - - if ((spr->defs.myauth.proto != 0 && spr->defs.myauth.proto != PPP_PAP && - spr->defs.myauth.proto != PPP_CHAP) || - (spr->defs.hisauth.proto != 0 && spr->defs.hisauth.proto != PPP_PAP && - spr->defs.hisauth.proto != PPP_CHAP)) { - rv = EINVAL; - break; - } - - if (spr->defs.myauth.proto == 0) - /* resetting myauth */ - bzero(&sp->myauth, sizeof sp->myauth); - else { - /* setting/changing myauth */ - sp->myauth.proto = spr->defs.myauth.proto; - bcopy(spr->defs.myauth.name, sp->myauth.name, AUTHNAMELEN); - if (spr->defs.myauth.secret[0] != '\0') - bcopy(spr->defs.myauth.secret, sp->myauth.secret, - AUTHKEYLEN); - } - if (spr->defs.hisauth.proto == 0) - /* resetting hisauth */ - bzero(&sp->hisauth, sizeof sp->hisauth); - else { - /* setting/changing hisauth */ - sp->hisauth.proto = spr->defs.hisauth.proto; - sp->hisauth.flags = spr->defs.hisauth.flags; - bcopy(spr->defs.hisauth.name, sp->hisauth.name, AUTHNAMELEN); - if (spr->defs.hisauth.secret[0] != '\0') - bcopy(spr->defs.hisauth.secret, sp->hisauth.secret, - AUTHKEYLEN); - } - /* set LCP restart timer timeout */ - if (spr->defs.lcp.timeout != 0) - sp->lcp.timeout = spr->defs.lcp.timeout * hz / 1000; - /* set VJ enable and IPv6 disable flags */ -#ifdef INET - if (spr->defs.enable_vj) - sp->confflags |= CONF_ENABLE_VJ; - else - sp->confflags &= ~CONF_ENABLE_VJ; -#endif -#ifdef INET6 - if (spr->defs.enable_ipv6) - sp->confflags |= CONF_ENABLE_IPV6; - else - sp->confflags &= ~CONF_ENABLE_IPV6; -#endif - break; - - default: - rv = EINVAL; - } - - quit: - free(spr, M_TEMP); - - return (rv); -} - -static void -sppp_phase_network(struct sppp *sp) -{ - STDDCL; - int i; - u_long mask; - - sp->pp_phase = PHASE_NETWORK; - - if (debug) - log(LOG_DEBUG, SPP_FMT "phase %s\n", SPP_ARGS(ifp), - sppp_phase_name(sp->pp_phase)); - - /* Notify NCPs now. */ - for (i = 0; i < IDX_COUNT; i++) - if ((cps[i])->flags & CP_NCP) - (cps[i])->Open(sp); - - /* Send Up events to all NCPs. */ - for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1) - if ((sp->lcp.protos & mask) && ((cps[i])->flags & CP_NCP)) - (cps[i])->Up(sp); - - /* if no NCP is starting, all this was in vain, close down */ - sppp_lcp_check_and_close(sp); -} - -static const char * -sppp_cp_type_name(u_char type) -{ - static char buf[12]; - switch (type) { - case CONF_REQ: return "conf-req"; - case CONF_ACK: return "conf-ack"; - case CONF_NAK: return "conf-nak"; - case CONF_REJ: return "conf-rej"; - case TERM_REQ: return "term-req"; - case TERM_ACK: return "term-ack"; - case CODE_REJ: return "code-rej"; - case PROTO_REJ: return "proto-rej"; - case ECHO_REQ: return "echo-req"; - case ECHO_REPLY: return "echo-reply"; - case DISC_REQ: return "discard-req"; - } - snprintf (buf, sizeof(buf), "cp/0x%x", type); - return buf; -} - -static const char * -sppp_auth_type_name(u_short proto, u_char type) -{ - static char buf[12]; - switch (proto) { - case PPP_CHAP: - switch (type) { - case CHAP_CHALLENGE: return "challenge"; - case CHAP_RESPONSE: return "response"; - case CHAP_SUCCESS: return "success"; - case CHAP_FAILURE: return "failure"; - } - case PPP_PAP: - switch (type) { - case PAP_REQ: return "req"; - case PAP_ACK: return "ack"; - case PAP_NAK: return "nak"; - } - } - snprintf (buf, sizeof(buf), "auth/0x%x", type); - return buf; -} - -static const char * -sppp_lcp_opt_name(u_char opt) -{ - static char buf[12]; - switch (opt) { - case LCP_OPT_MRU: return "mru"; - case LCP_OPT_ASYNC_MAP: return "async-map"; - case LCP_OPT_AUTH_PROTO: return "auth-proto"; - case LCP_OPT_QUAL_PROTO: return "qual-proto"; - case LCP_OPT_MAGIC: return "magic"; - case LCP_OPT_PROTO_COMP: return "proto-comp"; - case LCP_OPT_ADDR_COMP: return "addr-comp"; - } - snprintf (buf, sizeof(buf), "lcp/0x%x", opt); - return buf; -} - -#ifdef INET -static const char * -sppp_ipcp_opt_name(u_char opt) -{ - static char buf[12]; - switch (opt) { - case IPCP_OPT_ADDRESSES: return "addresses"; - case IPCP_OPT_COMPRESSION: return "compression"; - case IPCP_OPT_ADDRESS: return "address"; - } - snprintf (buf, sizeof(buf), "ipcp/0x%x", opt); - return buf; -} -#endif - -#ifdef INET6 -static const char * -sppp_ipv6cp_opt_name(u_char opt) -{ - static char buf[12]; - switch (opt) { - case IPV6CP_OPT_IFID: return "ifid"; - case IPV6CP_OPT_COMPRESSION: return "compression"; - } - sprintf (buf, "0x%x", opt); - return buf; -} -#endif - -static const char * -sppp_state_name(int state) -{ - switch (state) { - case STATE_INITIAL: return "initial"; - case STATE_STARTING: return "starting"; - case STATE_CLOSED: return "closed"; - case STATE_STOPPED: return "stopped"; - case STATE_CLOSING: return "closing"; - case STATE_STOPPING: return "stopping"; - case STATE_REQ_SENT: return "req-sent"; - case STATE_ACK_RCVD: return "ack-rcvd"; - case STATE_ACK_SENT: return "ack-sent"; - case STATE_OPENED: return "opened"; - } - return "illegal"; -} - -static const char * -sppp_phase_name(enum ppp_phase phase) -{ - switch (phase) { - case PHASE_DEAD: return "dead"; - case PHASE_ESTABLISH: return "establish"; - case PHASE_TERMINATE: return "terminate"; - case PHASE_AUTHENTICATE: return "authenticate"; - case PHASE_NETWORK: return "network"; - } - return "illegal"; -} - -static const char * -sppp_proto_name(u_short proto) -{ - static char buf[12]; - switch (proto) { - case PPP_LCP: return "lcp"; - case PPP_IPCP: return "ipcp"; - case PPP_PAP: return "pap"; - case PPP_CHAP: return "chap"; - case PPP_IPV6CP: return "ipv6cp"; - } - snprintf(buf, sizeof(buf), "proto/0x%x", (unsigned)proto); - return buf; -} - -static void -sppp_print_bytes(const u_char *p, u_short len) -{ - if (len) - log(-1, " %*D", len, p, "-"); -} - -static void -sppp_print_string(const char *p, u_short len) -{ - u_char c; - - while (len-- > 0) { - c = *p++; - /* - * Print only ASCII chars directly. RFC 1994 recommends - * using only them, but we don't rely on it. */ - if (c < ' ' || c > '~') - log(-1, "\\x%x", c); - else - log(-1, "%c", c); - } -} - -#ifdef INET -static const char * -sppp_dotted_quad(u_long addr) -{ - static char s[16]; - sprintf(s, "%d.%d.%d.%d", - (int)((addr >> 24) & 0xff), - (int)((addr >> 16) & 0xff), - (int)((addr >> 8) & 0xff), - (int)(addr & 0xff)); - return s; -} -#endif - -static int -sppp_strnlen(u_char *p, int max) -{ - int len; - - for (len = 0; len < max && *p; ++p) - ++len; - return len; -} - -/* a dummy, used to drop uninteresting events */ -static void -sppp_null(struct sppp *unused) -{ - /* do just nothing */ -} diff --git a/sys/netgraph/ng_sppp.c b/sys/netgraph/ng_sppp.c deleted file mode 100644 index 78e205e0d715..000000000000 --- a/sys/netgraph/ng_sppp.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * ng_sppp.c Netgraph to Sppp module. - */ - -/*- - * Copyright (C) 2002-2004 Cronyx Engineering. - * Copyright (C) 2002-2004 Roman Kurakin - * - * This software is distributed with NO WARRANTIES, not even the implied - * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Authors grant any other persons or organisations a permission to use, - * modify and redistribute this software in source and binary forms, - * as long as this message is kept with the software, all derivative - * works or modified versions. - * - * Cronyx Id: ng_sppp.c,v 1.1.2.10 2004/03/01 15:17:21 rik Exp $ - */ -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#ifdef NG_SEPARATE_MALLOC -static MALLOC_DEFINE(M_NETGRAPH_SPPP, "netgraph_sppp", "netgraph sppp node"); -#else -#define M_NETGRAPH_SPPP M_NETGRAPH -#endif - -/* Node private data */ -struct ng_sppp_private { - struct ifnet *ifp; /* Our interface */ - int unit; /* Interface unit number */ - node_p node; /* Our netgraph node */ - hook_p hook; /* Hook */ -}; -typedef struct ng_sppp_private *priv_p; - -/* Interface methods */ -static void ng_sppp_start (struct ifnet *ifp); -static int ng_sppp_ioctl (struct ifnet *ifp, u_long cmd, caddr_t data); - -/* Netgraph methods */ -static ng_constructor_t ng_sppp_constructor; -static ng_rcvmsg_t ng_sppp_rcvmsg; -static ng_shutdown_t ng_sppp_shutdown; -static ng_newhook_t ng_sppp_newhook; -static ng_rcvdata_t ng_sppp_rcvdata; -static ng_disconnect_t ng_sppp_disconnect; - -/* List of commands and how to convert arguments to/from ASCII */ -static const struct ng_cmdlist ng_sppp_cmds[] = { - { - NGM_SPPP_COOKIE, - NGM_SPPP_GET_IFNAME, - "getifname", - NULL, - &ng_parse_string_type - }, - { 0 } -}; - -/* Node type descriptor */ -static struct ng_type typestruct = { - .version = NG_ABI_VERSION, - .name = NG_SPPP_NODE_TYPE, - .constructor = ng_sppp_constructor, - .rcvmsg = ng_sppp_rcvmsg, - .shutdown = ng_sppp_shutdown, - .newhook = ng_sppp_newhook, - .rcvdata = ng_sppp_rcvdata, - .disconnect = ng_sppp_disconnect, - .cmdlist = ng_sppp_cmds, -}; -NETGRAPH_INIT(sppp, &typestruct); - -MODULE_DEPEND (ng_sppp, sppp, 1, 1, 1); - -/* We keep a bitmap indicating which unit numbers are free. - Zero means the unit number is free, one means it's taken. */ -static unsigned char *ng_sppp_units = NULL; -static unsigned char ng_sppp_units_len = 0; -static unsigned char ng_units_in_use = 0; - -/* - * Find the first free unit number for a new interface. - * Increase the size of the unit bitmap as necessary. - */ -static __inline void -ng_sppp_get_unit (int *unit) -{ - int index, bit; - unsigned char mask; - - for (index = 0; index < ng_sppp_units_len - && ng_sppp_units[index] == 0xFF; index++); - if (index == ng_sppp_units_len) { /* extend array */ - unsigned char *newarray; - int newlen; - - newlen = (2 * ng_sppp_units_len) + sizeof (*ng_sppp_units); - newarray = malloc (newlen * sizeof (*ng_sppp_units), - M_NETGRAPH_SPPP, M_WAITOK); - bcopy (ng_sppp_units, newarray, - ng_sppp_units_len * sizeof (*ng_sppp_units)); - bzero (newarray + ng_sppp_units_len, - newlen - ng_sppp_units_len); - if (ng_sppp_units != NULL) - free (ng_sppp_units, M_NETGRAPH_SPPP); - ng_sppp_units = newarray; - ng_sppp_units_len = newlen; - } - mask = ng_sppp_units[index]; - for (bit = 0; (mask & 1) != 0; bit++) - mask >>= 1; - KASSERT ((bit >= 0 && bit < NBBY), - ("%s: word=%d bit=%d", __func__, ng_sppp_units[index], bit)); - ng_sppp_units[index] |= (1 << bit); - *unit = (index * NBBY) + bit; - ng_units_in_use++; -} - -/* - * Free a no longer needed unit number. - */ -static __inline void -ng_sppp_free_unit (int unit) -{ - int index, bit; - - index = unit / NBBY; - bit = unit % NBBY; - KASSERT (index < ng_sppp_units_len, - ("%s: unit=%d len=%d", __func__, unit, ng_sppp_units_len)); - KASSERT ((ng_sppp_units[index] & (1 << bit)) != 0, - ("%s: unit=%d is free", __func__, unit)); - ng_sppp_units[index] &= ~(1 << bit); - - ng_units_in_use--; - if (ng_units_in_use == 0) { - free (ng_sppp_units, M_NETGRAPH_SPPP); - ng_sppp_units_len = 0; - ng_sppp_units = NULL; - } -} - -/************************************************************************ - INTERFACE STUFF - ************************************************************************/ - -/* - * Process an ioctl for the interface - */ -static int -ng_sppp_ioctl (struct ifnet *ifp, u_long command, caddr_t data) -{ - int error = 0; - - error = sppp_ioctl (ifp, command, data); - if (error) - return error; - - return error; -} - -/* - * This routine should never be called - */ - -static void -ng_sppp_start (struct ifnet *ifp) -{ - struct mbuf *m; - int len, error = 0; - priv_p priv = ifp->if_softc; - - /* Check interface flags */ - /* - * This has side effects. It is not good idea to stop sending if we - * are not UP. If we are not running we still want to send LCP term - * packets. - */ -/* if (!((ifp->if_flags & IFF_UP) && */ -/* (ifp->if_drv_flags & IFF_DRV_RUNNING))) { */ -/* return;*/ -/* }*/ - - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) - return; - - if (!priv->hook) - return; - - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - - while ((m = sppp_dequeue (ifp)) != NULL) { - BPF_MTAP (ifp, m); - len = m->m_pkthdr.len; - - NG_SEND_DATA_ONLY (error, priv->hook, m); - - if (error) { - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - return; - } - } - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; -} - -/************************************************************************ - NETGRAPH NODE STUFF - ************************************************************************/ - -/* - * Constructor for a node - */ -static int -ng_sppp_constructor (node_p node) -{ - struct sppp *pp; - struct ifnet *ifp; - priv_p priv; - - /* Allocate node and interface private structures */ - priv = malloc(sizeof(*priv), M_NETGRAPH_SPPP, M_WAITOK | M_ZERO); - - ifp = if_alloc(IFT_PPP); - if (ifp == NULL) { - free (priv, M_NETGRAPH_SPPP); - return (ENOSPC); - } - pp = IFP2SP(ifp); - - /* Link them together */ - ifp->if_softc = priv; - priv->ifp = ifp; - - /* Get an interface unit number */ - ng_sppp_get_unit(&priv->unit); - - /* Link together node and private info */ - NG_NODE_SET_PRIVATE (node, priv); - priv->node = node; - - /* Initialize interface structure */ - if_initname (SP2IFP(pp), NG_SPPP_IFACE_NAME, priv->unit); - ifp->if_start = ng_sppp_start; - ifp->if_ioctl = ng_sppp_ioctl; - ifp->if_flags = (IFF_POINTOPOINT|IFF_MULTICAST); - - /* Give this node the same name as the interface (if possible) */ - if (ng_name_node(node, SP2IFP(pp)->if_xname) != 0) - log (LOG_WARNING, "%s: can't acquire netgraph name\n", - SP2IFP(pp)->if_xname); - - /* Attach the interface */ - sppp_attach (ifp); - if_attach (ifp); - bpfattach (ifp, DLT_NULL, sizeof(u_int32_t)); - - /* Done */ - return (0); -} - -/* - * Give our ok for a hook to be added - */ -static int -ng_sppp_newhook (node_p node, hook_p hook, const char *name) -{ - priv_p priv = NG_NODE_PRIVATE (node); - - if (strcmp (name, NG_SPPP_HOOK_DOWNSTREAM) != 0) - return (EINVAL); - - if (priv->hook) - return (EISCONN); - - priv->hook = hook; - NG_HOOK_SET_PRIVATE (hook, priv); - - return (0); -} - -/* - * Receive a control message - */ -static int -ng_sppp_rcvmsg (node_p node, item_p item, hook_p lasthook) -{ - const priv_p priv = NG_NODE_PRIVATE (node); - struct ng_mesg *msg = NULL; - struct ng_mesg *resp = NULL; - struct sppp *const pp = IFP2SP(priv->ifp); - int error = 0; - - NGI_GET_MSG (item, msg); - switch (msg->header.typecookie) { - case NGM_SPPP_COOKIE: - switch (msg->header.cmd) { - case NGM_SPPP_GET_IFNAME: - NG_MKRESPONSE (resp, msg, IFNAMSIZ, M_NOWAIT); - if (!resp) { - error = ENOMEM; - break; - } - strlcpy(resp->data, SP2IFP(pp)->if_xname, IFNAMSIZ); - break; - - default: - error = EINVAL; - break; - } - break; - default: - error = EINVAL; - break; - } - NG_RESPOND_MSG (error, node, item, resp); - NG_FREE_MSG (msg); - return (error); -} - -/* - * Recive data from a hook. Pass the packet to the correct input routine. - */ -static int -ng_sppp_rcvdata (hook_p hook, item_p item) -{ - struct mbuf *m; - const priv_p priv = NG_NODE_PRIVATE (NG_HOOK_NODE (hook)); - struct sppp *const pp = IFP2SP(priv->ifp); - - NGI_GET_M (item, m); - NG_FREE_ITEM (item); - /* Sanity checks */ - KASSERT (m->m_flags & M_PKTHDR, ("%s: not pkthdr", __func__)); - if ((SP2IFP(pp)->if_flags & IFF_UP) == 0) { - NG_FREE_M (m); - return (ENETDOWN); - } - - /* Update interface stats */ - if_inc_counter(SP2IFP(pp), IFCOUNTER_IPACKETS, 1); - - /* Note receiving interface */ - m->m_pkthdr.rcvif = SP2IFP(pp); - - /* Berkeley packet filter */ - BPF_MTAP (SP2IFP(pp), m); - - /* Send packet */ - sppp_input (SP2IFP(pp), m); - return 0; -} - -/* - * Shutdown and remove the node and its associated interface. - */ -static int -ng_sppp_shutdown (node_p node) -{ - const priv_p priv = NG_NODE_PRIVATE(node); - /* Detach from the packet filter list of interfaces. */ - bpfdetach (priv->ifp); - sppp_detach (priv->ifp); - if_detach (priv->ifp); - if_free(priv->ifp); - ng_sppp_free_unit (priv->unit); - free (priv, M_NETGRAPH_SPPP); - NG_NODE_SET_PRIVATE (node, NULL); - NG_NODE_UNREF (node); - return (0); -} - -/* - * Hook disconnection. - */ -static int -ng_sppp_disconnect (hook_p hook) -{ - const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); - - if (priv) - priv->hook = NULL; - - return (0); -} diff --git a/sys/netgraph/ng_sppp.h b/sys/netgraph/ng_sppp.h deleted file mode 100644 index be1631e48f36..000000000000 --- a/sys/netgraph/ng_sppp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ng_sppp.h Netgraph to Sppp module. - */ - -/*- - * Copyright (C) 2002-2004 Cronyx Engineering. - * Copyright (C) 2002-2004 Roman Kurakin - * - * This software is distributed with NO WARRANTIES, not even the implied - * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Authors grant any other persons or organisations a permission to use, - * modify and redistribute this software in source and binary forms, - * as long as this message is kept with the software, all derivative - * works or modified versions. - * - * $FreeBSD$ - * Cronyx Id: ng_sppp.h,v 1.1.2.6 2004/03/01 15:17:21 rik Exp $ - */ - -#ifndef _NETGRAPH_SPPP_H_ -#define _NETGRAPH_SPPP_H_ - -/* Node type name and magic cookie */ -#define NG_SPPP_NODE_TYPE "sppp" -#define NGM_SPPP_COOKIE 1040804655 - -/* Interface base name */ -#define NG_SPPP_IFACE_NAME "sppp" - -/* My hook names */ -#define NG_SPPP_HOOK_DOWNSTREAM "downstream" - -/* Netgraph commands */ -enum { - NGM_SPPP_GET_IFNAME = 1, /* returns struct ng_sppp_ifname */ -}; - -#endif /* _NETGRAPH_SPPP_H_ */ diff --git a/sys/x86/conf/NOTES b/sys/x86/conf/NOTES index ad38de1a95fd..26806a75ac21 100644 --- a/sys/x86/conf/NOTES +++ b/sys/x86/conf/NOTES @@ -103,3 +103,8 @@ envvar hint.fd.0.at="fdc0" envvar hint.fd.0.drive="0" envvar hint.fd.1.at="fdc0" envvar hint.fd.1.drive="1" + +# cp: Cronyx Tau-PCI sync single/dual/four port +# V.35/RS-232/RS-530/RS-449/X.21/G.703/E1/E3/T3/STS-1 +# serial adaptor, requires NETGRAPH +device cp diff --git a/targets/pseudo/userland/Makefile.depend b/targets/pseudo/userland/Makefile.depend index 3cb074084826..84eb8912705b 100644 --- a/targets/pseudo/userland/Makefile.depend +++ b/targets/pseudo/userland/Makefile.depend @@ -129,7 +129,6 @@ DIRDEPS+= \ sbin/savecore \ sbin/setkey \ sbin/shutdown \ - sbin/spppcontrol \ sbin/swapon \ sbin/sysctl \ sbin/tunefs \