Index: ObsoleteFiles.inc =================================================================== --- ObsoleteFiles.inc +++ ObsoleteFiles.inc @@ -40,6 +40,17 @@ # xargs -n1 | sort | uniq -d; # done +# 2021XXXX +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 Index: UPDATING =================================================================== --- UPDATING +++ UPDATING @@ -27,6 +27,11 @@ world, or to merely disable the most expensive debugging functionality at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +2021XXXX: + 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: Index: lib/libc/net/getnameinfo.c =================================================================== --- lib/libc/net/getnameinfo.c +++ lib/libc/net/getnameinfo.c @@ -467,7 +467,7 @@ * 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) Index: lib/libnetgraph/debug.c =================================================================== --- lib/libnetgraph/debug.c +++ lib/libnetgraph/debug.c @@ -96,7 +96,6 @@ #include #include #include -#include #include #include #include @@ -172,7 +171,6 @@ COOKIE(SOCKET), COOKIE(SOURCE), COOKIE(SPLIT), - COOKIE(SPPP), COOKIE(TAG), COOKIE(TCPMSS), COOKIE(TEE), Index: libexec/rc/netstart =================================================================== --- libexec/rc/netstart +++ libexec/rc/netstart @@ -43,7 +43,6 @@ /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} Index: libexec/rc/rc.conf =================================================================== --- libexec/rc/rc.conf +++ libexec/rc/rc.conf @@ -262,12 +262,6 @@ # #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). Index: libexec/rc/rc.d/Makefile =================================================================== --- libexec/rc/rc.d/Makefile +++ libexec/rc/rc.d/Makefile @@ -96,7 +96,6 @@ savecore \ securelevel \ serial \ - sppp \ statd \ static_arp \ static_ndp \ Index: libexec/rc/rc.d/netif =================================================================== --- libexec/rc/rc.d/netif +++ 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 Index: libexec/rc/rc.d/sppp =================================================================== --- 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" Index: rescue/rescue/Makefile =================================================================== --- rescue/rescue/Makefile +++ rescue/rescue/Makefile @@ -101,7 +101,7 @@ 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 Index: sbin/Makefile =================================================================== --- sbin/Makefile +++ sbin/Makefile @@ -63,7 +63,6 @@ savecore \ setkey \ shutdown \ - spppcontrol \ swapon \ sysctl \ tunefs \ Index: sbin/sconfig/sconfig.8 =================================================================== --- sbin/sconfig/sconfig.8 +++ sbin/sconfig/sconfig.8 @@ -216,9 +216,6 @@ 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 @@ .Sh SEE ALSO .Xr stty 1 , .Xr ioctl 2 , -.Xr sppp 4 , .Xr ifconfig 8 , .Xr route 8 , -.Xr spppcontrol 8 .\"-------------------------------------------------------------- .Sh HISTORY The Index: sbin/spppcontrol/Makefile =================================================================== --- sbin/spppcontrol/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $FreeBSD$ - -PACKAGE= ppp - -PROG= spppcontrol -MAN= spppcontrol.8 -WARNS?= 2 - -.include Index: sbin/spppcontrol/Makefile.depend =================================================================== --- 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 Index: sbin/spppcontrol/spppcontrol.8 =================================================================== --- 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. Index: sbin/spppcontrol/spppcontrol.c =================================================================== --- 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; -} Index: share/man/man4/Makefile =================================================================== --- share/man/man4/Makefile +++ share/man/man4/Makefile @@ -378,7 +378,6 @@ ng_socket.4 \ ng_source.4 \ ng_split.4 \ - ng_sppp.4 \ ng_sscfu.4 \ ng_sscop.4 \ ng_tag.4 \ @@ -528,7 +527,6 @@ spigen.4 \ ${_spkr.4} \ splash.4 \ - sppp.4 \ ste.4 \ stf.4 \ stge.4 \ Index: share/man/man4/man4.i386/ce.4 =================================================================== --- share/man/man4/man4.i386/ce.4 +++ share/man/man4/man4.i386/ce.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 30, 2006 +.Dd October 20, 2021 .Dt CE 4 i386 .Os .Sh NAME @@ -44,29 +44,19 @@ .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 @@ .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 @@ .Fx 5.5 and .Fx 4.11 . -The -.Nm -driver for previous versions of -.Fx -is available from -.Pa http://www.cronyx.ru/ . Index: share/man/man4/man4.i386/cp.4 =================================================================== --- share/man/man4/man4.i386/cp.4 +++ 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 20, 2021 .Dt CP 4 i386 .Os .Sh NAME @@ -34,28 +34,19 @@ 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 @@ 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 @@ .Fx 5.3 and .Fx 4.11 . -The -.Nm -driver for previous versions of -.Fx -is available from -.Pa http://www.cronyx.ru/ . Index: share/man/man4/netgraph.4 =================================================================== --- share/man/man4/netgraph.4 +++ share/man/man4/netgraph.4 @@ -1454,7 +1454,6 @@ .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 , Index: share/man/man4/ng_sppp.4 =================================================================== --- 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 Index: share/man/man4/sppp.4 =================================================================== --- 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. Index: share/man/man5/rc.conf.5 =================================================================== --- share/man/man5/rc.conf.5 +++ share/man/man5/rc.conf.5 @@ -1941,21 +1941,6 @@ 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 Index: sys/conf/NOTES =================================================================== --- sys/conf/NOTES +++ sys/conf/NOTES @@ -810,7 +810,6 @@ 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_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. Index: sys/conf/files =================================================================== --- sys/conf/files +++ sys/conf/files @@ -4157,8 +4157,6 @@ 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_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_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 Index: sys/conf/files.i386 =================================================================== --- sys/conf/files.i386 +++ sys/conf/files.i386 @@ -33,9 +33,6 @@ 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 Index: sys/conf/files.x86 =================================================================== --- sys/conf/files.x86 +++ sys/conf/files.x86 @@ -79,6 +79,9 @@ 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 Index: sys/conf/options.i386 =================================================================== --- sys/conf/options.i386 +++ sys/conf/options.i386 @@ -88,9 +88,6 @@ # 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 Index: sys/dev/ce/if_ce.c =================================================================== --- sys/dev/ce/if_ce.c +++ sys/dev/ce/if_ce.c @@ -38,42 +38,18 @@ #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 @@ #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 @@ 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_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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ return ENOTTY; } -#ifdef NETGRAPH static int ng_ce_constructor (node_p node) { drv_t *d = NG_NODE_PRIVATE (node); @@ -2059,7 +1760,6 @@ } return 0; } -#endif static int ce_modevent (module_t mod, int type, void *unused) { @@ -2068,10 +1768,8 @@ 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 @@ 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 @@ return 0; } -#ifdef NETGRAPH static struct ng_type typestruct = { .version = NG_ABI_VERSION, .name = NG_CE_NODE_TYPE, @@ -2110,13 +1805,8 @@ .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 Index: sys/dev/ce/ng_ce.h =================================================================== --- sys/dev/ce/ng_ce.h +++ 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 */ Index: sys/dev/cp/if_cp.c =================================================================== --- sys/dev/cp/if_cp.c +++ sys/dev/cp/if_cp.c @@ -47,32 +47,14 @@ #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 @@ 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_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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } mtx_destroy (&d->queue.ifq_mtx); mtx_destroy (&d->hi_queue.ifq_mtx); -#endif destroy_dev (d->devt); } @@ -639,96 +552,6 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ { drv_t *d = c->sys; struct mbuf *m; -#ifdef NETGRAPH int error; -#endif if (! d->running) return; @@ -885,24 +692,12 @@ 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 @@ 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 @@ 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 @@ 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 @@ return ENOTTY; } -#ifdef NETGRAPH static int ng_cp_constructor (node_p node) { drv_t *d = NG_NODE_PRIVATE (node); @@ -2209,7 +1916,6 @@ } return 0; } -#endif static int cp_modevent (module_t mod, int type, void *unused) { @@ -2217,10 +1923,8 @@ 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 @@ 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 @@ return 0; } -#ifdef NETGRAPH static struct ng_type typestruct = { .version = NG_ABI_VERSION, .name = NG_CP_NODE_TYPE, @@ -2258,12 +1959,7 @@ .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); Index: sys/dev/cp/ng_cp.h =================================================================== --- sys/dev/cp/ng_cp.h +++ 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 */ Index: sys/i386/conf/NOTES =================================================================== --- sys/i386/conf/NOTES +++ sys/i386/conf/NOTES @@ -490,12 +490,7 @@ # 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 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 Index: sys/i386/include/cserial.h =================================================================== --- /dev/null +++ sys/i386/include/cserial.h @@ -1,519 +0,0 @@ -/*- - * Ioctl interface to Cronyx serial drivers. - * - * Copyright (C) 1997-2002 Cronyx Engineering. - * Author: Serge Vakulenko, - * - * Copyright (C) 2001-2005 Cronyx Engineering. - * Author: Roman Kurakin, - * - * Copyright (C) 2004-2005 Cronyx Engineering. - * Author: Leo Yuriev, - * - * 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. - * - * Cronyx Id: cserial.h,v 1.4.2.2 2005/11/09 13:01:35 rik Exp $ - * $FreeBSD$ - */ - -/* - * General channel statistics. - */ -struct serial_statistics { - unsigned long rintr; /* receive interrupts */ - unsigned long tintr; /* transmit interrupts */ - unsigned long mintr; /* modem interrupts */ - unsigned long ibytes; /* input bytes */ - unsigned long ipkts; /* input packets */ - unsigned long ierrs; /* input errors */ - unsigned long obytes; /* output bytes */ - unsigned long opkts; /* output packets */ - unsigned long oerrs; /* output errors */ -}; - -/* - * Statistics for E1/G703 channels. - */ -struct e1_counters { - unsigned long bpv; /* bipolar violations */ - unsigned long fse; /* frame sync errors */ - unsigned long crce; /* CRC errors */ - unsigned long rcrce; /* remote CRC errors (E-bit) */ - unsigned long uas; /* unavailable seconds */ - unsigned long les; /* line errored seconds */ - unsigned long es; /* errored seconds */ - unsigned long bes; /* bursty errored seconds */ - unsigned long ses; /* severely errored seconds */ - unsigned long oofs; /* out of frame seconds */ - unsigned long css; /* controlled slip seconds */ - unsigned long dm; /* degraded minutes */ -}; - -struct e1_statistics { - unsigned long status; /* line status bit mask */ - unsigned long cursec; /* seconds in current interval */ - unsigned long totsec; /* total seconds elapsed */ - struct e1_counters currnt; /* current 15-min interval data */ - struct e1_counters total; /* total statistics data */ - struct e1_counters interval [48]; /* 12 hour period data */ -}; - -struct e3_statistics { - unsigned long status; - unsigned long cursec; - unsigned long totsec; - unsigned long ccv; - unsigned long tcv; - unsigned long icv[48]; -}; - -#define M_ASYNC 0 /* asynchronous mode */ -#define M_HDLC 1 /* bit-sync mode (HDLC) */ -#define M_G703 2 -#define M_E1 3 - -/* - * Receive error codes. - */ -#define ER_FRAMING 1 /* framing error */ -#define ER_CHECKSUM 2 /* parity/CRC error */ -#define ER_BREAK 3 /* break state */ -#define ER_OVERFLOW 4 /* receive buffer overflow */ -#define ER_OVERRUN 5 /* receive fifo overrun */ -#define ER_UNDERRUN 6 /* transmit fifo underrun */ -#define ER_SCC_FRAMING 7 /* subchannel framing error */ -#define ER_SCC_OVERFLOW 8 /* subchannel receive buffer overflow */ -#define ER_SCC_OVERRUN 9 /* subchannel receiver overrun */ -#define ER_SCC_UNDERRUN 10 /* subchannel transmitter underrun */ -#define ER_BUS 11 /* system bus is too busy (e.g PCI) */ - -/* - * E1 channel status. - */ -#define E1_NOALARM 0x0001 /* no alarm present */ -#define E1_FARLOF 0x0002 /* receiving far loss of framing */ -#define E1_CRC4E 0x0004 /* crc4 errors */ -#define E1_AIS 0x0008 /* receiving all ones */ -#define E1_LOF 0x0020 /* loss of framing */ -#define E1_LOS 0x0040 /* loss of signal */ -#define E1_AIS16 0x0100 /* receiving all ones in timeslot 16 */ -#define E1_FARLOMF 0x0200 /* receiving alarm in timeslot 16 */ -#define E1_LOMF 0x0400 /* loss of multiframe sync */ -#define E1_TSTREQ 0x0800 /* test code detected */ -#define E1_TSTERR 0x1000 /* test error */ - -#define E3_LOS 0x00000002 /* Lost of synchronization */ -#define E3_TXE 0x00000004 /* Transmit error */ - -/* - * Query the mask of all registered channels, max 128. - */ -#define SERIAL_GETREGISTERED _IOR ('x', 0, char[16]) - -/* - * Attach/detach the protocol to the channel. - * The protocol is given by its name, char[8]. - * For example "async", "hdlc", "cisco", "fr", "ppp". - */ -#define SERIAL_GETPROTO _IOR ('x', 1, char [8]) -#define SERIAL_SETPROTO _IOW ('x', 1, char [8]) - -/* - * Query/set the hardware mode for the channel. - */ -#define SERIAL_GETMODE _IOR ('x', 2, int) -#define SERIAL_SETMODE _IOW ('x', 2, int) - -#define SERIAL_ASYNC 1 -#define SERIAL_HDLC 2 -#define SERIAL_RAW 3 - -/* - * Get/clear the channel statistics. - */ -#define SERIAL_GETSTAT _IOR ('x', 3, struct serial_statistics) -#define SERIAL_GETESTAT _IOR ('x', 3, struct e1_statistics) -#define SERIAL_GETE3STAT _IOR ('x', 3, struct e3_statistics) -#define SERIAL_CLRSTAT _IO ('x', 3) - -/* - * Query/set the synchronization mode and baud rate. - * If baud==0 then the external clock is used. - */ -#define SERIAL_GETBAUD _IOR ('x', 4, long) -#define SERIAL_SETBAUD _IOW ('x', 4, long) - -/* - * Query/set the internal loopback mode, - * useful for debugging purposes. - */ -#define SERIAL_GETLOOP _IOR ('x', 5, int) -#define SERIAL_SETLOOP _IOW ('x', 5, int) - -/* - * Query/set the DPLL mode, commonly used with NRZI - * for channels lacking synchro signals. - */ -#define SERIAL_GETDPLL _IOR ('x', 6, int) -#define SERIAL_SETDPLL _IOW ('x', 6, int) - -/* - * Query/set the NRZI encoding (default is NRZ). - */ -#define SERIAL_GETNRZI _IOR ('x', 7, int) -#define SERIAL_SETNRZI _IOW ('x', 7, int) - -/* - * Invert receive and transmit clock. - */ -#define SERIAL_GETINVCLK _IOR ('x', 8, int) -#define SERIAL_SETINVCLK _IOW ('x', 8, int) - -/* - * Query/set the E1/G703 synchronization mode. - */ -#define SERIAL_GETCLK _IOR ('x', 9, int) -#define SERIAL_SETCLK _IOW ('x', 9, int) - -#define E1CLK_RECOVERY -1 -#define E1CLK_INTERNAL 0 -#define E1CLK_RECEIVE 1 -#define E1CLK_RECEIVE_CHAN0 2 -#define E1CLK_RECEIVE_CHAN1 3 -#define E1CLK_RECEIVE_CHAN2 4 -#define E1CLK_RECEIVE_CHAN3 5 - -/* - * Query/set the E1 timeslot mask. - */ -#define SERIAL_GETTIMESLOTS _IOR ('x', 10, long) -#define SERIAL_SETTIMESLOTS _IOW ('x', 10, long) - -/* - * Query/set the E1 subchannel timeslot mask. - */ -#define SERIAL_GETSUBCHAN _IOR ('x', 11, long) -#define SERIAL_SETSUBCHAN _IOW ('x', 11, long) - -/* - * Query/set the high input sensitivity mode (E1). - */ -#define SERIAL_GETHIGAIN _IOR ('x', 12, int) -#define SERIAL_SETHIGAIN _IOW ('x', 12, int) - -/* - * Query the input signal level in santibells. - */ -#define SERIAL_GETLEVEL _IOR ('x', 13, int) - -/* - * Get the channel name. - */ -#define SERIAL_GETNAME _IOR ('x', 14, char [32]) - -/* - * Get version string. - */ -#define SERIAL_GETVERSIONSTRING _IOR ('x', 15, char [256]) - -/* - * Query/set master channel. - */ -#define SERIAL_GETMASTER _IOR ('x', 16, char [16]) -#define SERIAL_SETMASTER _IOW ('x', 16, char [16]) - -/* - * Query/set keepalive. - */ -#define SERIAL_GETKEEPALIVE _IOR ('x', 17, int) -#define SERIAL_SETKEEPALIVE _IOW ('x', 17, int) - -/* - * Query/set E1 configuration. - */ -#define SERIAL_GETCFG _IOR ('x', 18, char) -#define SERIAL_SETCFG _IOW ('x', 18, char) - -/* - * Query/set debug. - */ -#define SERIAL_GETDEBUG _IOR ('x', 19, int) -#define SERIAL_SETDEBUG _IOW ('x', 19, int) - -/* - * Query/set phony mode (E1). - */ -#define SERIAL_GETPHONY _IOR ('x', 20, int) -#define SERIAL_SETPHONY _IOW ('x', 20, int) - -/* - * Query/set timeslot 16 usage mode (E1). - */ -#define SERIAL_GETUSE16 _IOR ('x', 21, int) -#define SERIAL_SETUSE16 _IOW ('x', 21, int) - -/* - * Query/set crc4 mode (E1). - */ -#define SERIAL_GETCRC4 _IOR ('x', 22, int) -#define SERIAL_SETCRC4 _IOW ('x', 22, int) - -/* - * Query/set the timeout to recover after transmit interrupt loss. - * If timo==0 recover will be disabled. - */ -#define SERIAL_GETTIMO _IOR ('x', 23, long) -#define SERIAL_SETTIMO _IOW ('x', 23, long) - -/* - * Query/set port type for old models of Sigma - * -1 Fixed or cable select - * 0 RS-232 - * 1 V35 - * 2 RS-449 - * 3 E1 (only for Windows 2000) - * 4 G.703 (only for Windows 2000) - * 5 DATA (only for Windows 2000) - * 6 E3 (only for Windows 2000) - * 7 T3 (only for Windows 2000) - * 8 STS1 (only for Windows 2000) - */ -#define SERIAL_GETPORT _IOR ('x', 25, int) -#define SERIAL_SETPORT _IOW ('x', 25, int) - -/* - * Add the virtual channel DLCI (Frame Relay). - */ -#define SERIAL_ADDDLCI _IOW ('x', 26, int) - -/* - * Invert receive clock. - */ -#define SERIAL_GETINVRCLK _IOR ('x', 27, int) -#define SERIAL_SETINVRCLK _IOW ('x', 27, int) - -/* - * Invert transmit clock. - */ -#define SERIAL_GETINVTCLK _IOR ('x', 28, int) -#define SERIAL_SETINVTCLK _IOW ('x', 28, int) - -/* - * Unframed E1 mode. - */ -#define SERIAL_GETUNFRAM _IOR ('x', 29, int) -#define SERIAL_SETUNFRAM _IOW ('x', 29, int) - -/* - * E1 monitoring mode. - */ -#define SERIAL_GETMONITOR _IOR ('x', 30, int) -#define SERIAL_SETMONITOR _IOW ('x', 30, int) - -/* - * Interrupt number. - */ -#define SERIAL_GETIRQ _IOR ('x', 31, int) - -/* - * Reset. - */ -#define SERIAL_RESET _IO ('x', 32) - -/* - * Hard reset. - */ -#define SERIAL_HARDRESET _IO ('x', 33) - -/* - * Query cable type. - */ -#define SERIAL_GETCABLE _IOR ('x', 34, int) - -/* - * Assignment of HDLC ports to E1 channels. - */ -#define SERIAL_GETDIR _IOR ('x', 35, int) -#define SERIAL_SETDIR _IOW ('x', 35, int) - -struct dxc_table { /* cross-connector parameters */ - unsigned char ts [32]; /* timeslot number */ - unsigned char link [32]; /* E1 link number */ -}; - -/* - * DXC cross-connector settings for E1 channels. - */ -#define SERIAL_GETDXC _IOR ('x', 36, struct dxc_table) -#define SERIAL_SETDXC _IOW ('x', 36, struct dxc_table) - -/* - * Scrambler for G.703. - */ -#define SERIAL_GETSCRAMBLER _IOR ('x', 37, int) -#define SERIAL_SETSCRAMBLER _IOW ('x', 37, int) - -/* - * Length of cable for T3 and STS-1. - */ -#define SERIAL_GETCABLEN _IOR ('x', 38, int) -#define SERIAL_SETCABLEN _IOW ('x', 38, int) - -/* - * Remote loopback for E3, T3 and STS-1. - */ -#define SERIAL_GETRLOOP _IOR ('x', 39, int) -#define SERIAL_SETRLOOP _IOW ('x', 39, int) - -/* - * G.703 line code - */ -#define SERIAL_GETLCODE _IOR ('x', 40, int) -#define SERIAL_SETLCODE _IOW ('x', 40, int) - -/* - * MTU - */ -#define SERIAL_GETMTU _IOR ('x', 41, int) -#define SERIAL_SETMTU _IOW ('x', 41, int) - -/* - * Receive Queue Length - */ -#define SERIAL_GETRQLEN _IOR ('x', 42, int) -#define SERIAL_SETRQLEN _IOW ('x', 42, int) - -#ifdef __KERNEL__ -#ifdef CRONYX_LYSAP -# define LYSAP_PEER_ADD _IOWR('x', 101, lysap_peer_config_t) -# define LYSAP_PEER_REMOVE _IOW('x', 102, unsigned) -# define LYSAP_PEER_INFO _IOWR('x', 103, lysap_peer_info_t) -# define LYSAP_PEER_COUNT _IOR('x', 104, unsigned) -# define LYSAP_PEER_ENUM _IOWR('x', 105, unsigned) -# define LYSAP_PEER_CLEAR _IOW('x', 106, unsigned) - -# define LYSAP_CHAN_ADD _IOWR('x', 111, lysap_channel_config_t) -# define LYSAP_CHAN_REMOVE _IO('x', 112) -# define LYSAP_CHAN_INFO _IOR('x', 113, lysap_channel_info_t) -# define LYSAP_CHAN_COUNT _IOR('x', 114, unsigned) -# define LYSAP_CHAN_ENUM _IOWR('x', 115, unsigned) -# define LYSAP_CHAN_CLEAR _IO('x', 116) -# include "lysap-linux.h" -#else /* CRONYX_LYSAP */ - typedef struct _lysap_channel_t lysap_channel_t; - typedef struct _lysap_channel_config_t lysap_channel_config_t; - typedef struct _LYSAP_DeviceInterfaceConfig LYSAP_DeviceInterfaceConfig; - typedef struct _LYSAP_ChannelConfig LYSAP_ChannelConfig; - typedef struct _lysap_buf_t lysap_buf_t; -#endif /* !CRONYX_LYSAP */ - -/* - * Dynamic binder interface. - */ -typedef struct _chan_t chan_t; -typedef struct _proto_t proto_t; - -void binder_register_protocol (proto_t *p); -void binder_unregister_protocol (proto_t *p); - -int binder_register_channel (chan_t *h, char *prefix, int minor); -void binder_unregister_channel (chan_t *h); - -/* - * Hardware channel driver structure. - */ -struct sk_buff; - -struct _chan_t { - char name [16]; - int mtu; /* max packet size */ - int fifosz; /* total hardware i/o buffer size */ - int port; /* hardware base i/o port */ - int irq; /* hardware interrupt line */ - int minor; /* minor number 0..127, assigned by binder */ - int debug; /* debug level, 0..2 */ - int running; /* running, 0..1 */ - struct _proto_t *proto; /* protocol interface data */ - void *sw; /* protocol private data */ - void *hw; /* hardware layer private data */ - - /* Interface to protocol */ - int (*up) (chan_t *h); - void (*down) (chan_t *h); - int (*transmit) (chan_t *h, struct sk_buff *skb); - void (*set_dtr) (chan_t *h, int val); - void (*set_rts) (chan_t *h, int val); - int (*query_dtr) (chan_t *h); - int (*query_rts) (chan_t *h); - int (*query_dsr) (chan_t *h); - int (*query_cts) (chan_t *h); - int (*query_dcd) (chan_t *h); - - /* Interface to async protocol */ - void (*set_async_param) (chan_t *h, int baud, int bits, int parity, - int stop2, int ignpar, int rtscts, - int ixon, int ixany, int symstart, int symstop); - void (*send_break) (chan_t *h, int msec); - void (*send_xon) (chan_t *h); - void (*send_xoff) (chan_t *h); - void (*start_transmitter) (chan_t *h); - void (*stop_transmitter) (chan_t *h); - void (*flush_transmit_buffer) (chan_t *h); - - /* Control interface */ - int (*control) (chan_t *h, unsigned int cmd, unsigned long arg); - - /* LYSAP interface */ - struct lysap_t - { - lysap_channel_t *link; - int (*inspect_config)(chan_t *h, lysap_channel_config_t *, - LYSAP_DeviceInterfaceConfig *, LYSAP_ChannelConfig *); - unsigned long (*probe_freq)(chan_t *h, unsigned long freq); - unsigned long (*set_freq)(chan_t *h, unsigned long freq); - unsigned (*get_status)(chan_t *h); - int (*transmit) (chan_t *h, lysap_buf_t *b); - lysap_buf_t* (*alloc_buf) (chan_t *h, unsigned len); - int (*set_clock_master)(chan_t *h, int enable); - unsigned long (*get_master_freq)(chan_t *h); - } lysap; -}; - -/* - * Protocol driver structure. - */ -struct _proto_t { - char *name; - struct _proto_t *next; - - /* Interface to channel */ - void (*receive) (chan_t *h, struct sk_buff *skb); - void (*receive_error) (chan_t *h, int errcode); - void (*transmit) (chan_t *h); - void (*modem_event) (chan_t *h); - - /* Interface to binder */ - int (*open) (chan_t *h); - void (*close) (chan_t *h); - int (*read) (chan_t *h, unsigned short flg, char *buf, int len); - int (*write) (chan_t *h, unsigned short flg, const char *buf, int len); - int (*select) (chan_t *h, int type, void *st, struct file *filp); - struct fasync_struct *fasync; - - /* Control interface */ - int (*attach) (chan_t *h); - int (*detach) (chan_t *h); - int (*control) (chan_t *h, unsigned int cmd, unsigned long arg); - - /* LYSAP interface */ - void (*transmit_error) (chan_t *h, int errcode); - void (*lysap_notify_receive) (chan_t *h, lysap_buf_t *b); - void (*lysap_notify_transmit) (chan_t *h); - lysap_buf_t* (*lysap_get_data)(chan_t *h); -}; -#endif /* KERNEL */ Index: sys/modules/Makefile =================================================================== --- sys/modules/Makefile +++ sys/modules/Makefile @@ -353,7 +353,6 @@ ${_speaker} \ spi \ ${_splash} \ - ${_sppp} \ ste \ stge \ ${_sume} \ @@ -665,7 +664,6 @@ _safe= safe _speaker= speaker _splash= splash -_sppp= sppp _p2sb= p2sb _wbwd= wbwd Index: sys/modules/ce/Makefile =================================================================== --- sys/modules/ce/Makefile +++ 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 Index: sys/modules/cp/Makefile =================================================================== --- sys/modules/cp/Makefile +++ 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 Index: sys/modules/netgraph/Makefile =================================================================== --- sys/modules/netgraph/Makefile +++ sys/modules/netgraph/Makefile @@ -47,7 +47,6 @@ socket \ source \ split \ - sppp \ tag \ tcpmss \ tee \ Index: sys/modules/netgraph/sppp/Makefile =================================================================== --- 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 Index: sys/modules/sppp/Makefile =================================================================== --- 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 Index: sys/net/if_sppp.h =================================================================== --- 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_ */ Index: sys/net/if_spppfr.c =================================================================== --- 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; - } - } -} Index: sys/net/if_spppsubr.c =================================================================== --- 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 */ -} Index: sys/netgraph/ng_sppp.h =================================================================== --- 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_ */ Index: sys/netgraph/ng_sppp.c =================================================================== --- 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); -} Index: sys/x86/conf/NOTES =================================================================== --- sys/x86/conf/NOTES +++ sys/x86/conf/NOTES @@ -103,3 +103,8 @@ 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 Index: targets/pseudo/userland/Makefile.depend =================================================================== --- targets/pseudo/userland/Makefile.depend +++ targets/pseudo/userland/Makefile.depend @@ -129,7 +129,6 @@ sbin/savecore \ sbin/setkey \ sbin/shutdown \ - sbin/spppcontrol \ sbin/swapon \ sbin/sysctl \ sbin/tunefs \