LCOV - code coverage report
Current view: top level - net - if_spppsubr.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 2277 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 108 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: if_spppsubr.c,v 1.174 2018/02/19 08:59:52 mpi Exp $   */
       2             : /*
       3             :  * Synchronous PPP link level subroutines.
       4             :  *
       5             :  * Copyright (C) 1994-1996 Cronyx Engineering Ltd.
       6             :  * Author: Serge Vakulenko, <vak@cronyx.ru>
       7             :  *
       8             :  * Heavily revamped to conform to RFC 1661.
       9             :  * Copyright (C) 1997, Joerg Wunsch.
      10             :  *
      11             :  * RFC2472 IPv6CP support.
      12             :  * Copyright (C) 2000, Jun-ichiro itojun Hagino <itojun@iijlab.net>.
      13             :  *
      14             :  * Redistribution and use in source and binary forms, with or without
      15             :  * modification, are permitted provided that the following conditions are met:
      16             :  * 1. Redistributions of source code must retain the above copyright notice,
      17             :  *    this list of conditions and the following disclaimer.
      18             :  * 2. Redistributions in binary form must reproduce the above copyright notice,
      19             :  *    this list of conditions and the following disclaimer in the documentation
      20             :  *    and/or other materials provided with the distribution.
      21             :  *
      22             :  * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY
      23             :  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      24             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      25             :  * ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE
      26             :  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      27             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      28             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      29             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      30             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      31             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      32             :  * POSSIBILITY OF SUCH DAMAGE.
      33             :  *
      34             :  * From: Version 2.6, Tue May 12 17:10:39 MSD 1998
      35             :  */
      36             : 
      37             : #include <sys/param.h>
      38             : 
      39             : #include <sys/systm.h>
      40             : #include <sys/kernel.h>
      41             : #include <sys/sockio.h>
      42             : #include <sys/socket.h>
      43             : #include <sys/syslog.h>
      44             : #include <sys/malloc.h>
      45             : #include <sys/mbuf.h>
      46             : 
      47             : #include <sys/timeout.h>
      48             : #include <crypto/md5.h>
      49             : 
      50             : #include <net/if.h>
      51             : #include <net/if_var.h>
      52             : #include <net/netisr.h>
      53             : #include <net/if_types.h>
      54             : #include <net/route.h>
      55             : 
      56             : #include <sys/stdarg.h>
      57             : 
      58             : #include <netinet/in.h>
      59             : #include <netinet/in_var.h>
      60             : #include <netinet/ip.h>
      61             : 
      62             : #ifdef INET6
      63             : #include <netinet6/in6_ifattach.h>
      64             : #endif
      65             : 
      66             : #include <net/if_sppp.h>
      67             : 
      68             : # define UNTIMEOUT(fun, arg, handle)    \
      69             :         timeout_del(&(handle))
      70             : 
      71             : #define LOOPALIVECNT                    3       /* loopback detection tries */
      72             : #define MAXALIVECNT                     3       /* max. missed alive packets */
      73             : #define NORECV_TIME                     15      /* before we get worried */
      74             : 
      75             : /*
      76             :  * Interface flags that can be set in an ifconfig command.
      77             :  *
      78             :  * Setting link0 will make the link passive, i.e. it will be marked
      79             :  * as being administrative openable, but won't be opened to begin
      80             :  * with.  Incoming calls will be answered, or subsequent calls with
      81             :  * -link1 will cause the administrative open of the LCP layer.
      82             :  *
      83             :  * Setting link1 will cause the link to auto-dial only as packets
      84             :  * arrive to be sent.
      85             :  *
      86             :  * Setting IFF_DEBUG will syslog the option negotiation and state
      87             :  * transitions at level kern.debug.  Note: all logs consistently look
      88             :  * like
      89             :  *
      90             :  *   <if-name><unit>: <proto-name> <additional info...>
      91             :  *
      92             :  * with <if-name><unit> being something like "bppp0", and <proto-name>
      93             :  * being one of "lcp", "ipcp", "chap", "pap", etc.
      94             :  */
      95             : 
      96             : #define IFF_PASSIVE     IFF_LINK0       /* wait passively for connection */
      97             : #define IFF_AUTO        IFF_LINK1       /* auto-dial on output */
      98             : 
      99             : #define PPP_ALLSTATIONS 0xff            /* All-Stations broadcast address */
     100             : #define PPP_UI          0x03            /* Unnumbered Information */
     101             : #define PPP_IP          0x0021          /* Internet Protocol */
     102             : #define PPP_ISO         0x0023          /* ISO OSI Protocol */
     103             : #define PPP_XNS         0x0025          /* Xerox NS Protocol */
     104             : #define PPP_IPX         0x002b          /* Novell IPX Protocol */
     105             : #define PPP_IPV6        0x0057          /* Internet Protocol v6 */
     106             : #define PPP_LCP         0xc021          /* Link Control Protocol */
     107             : #define PPP_PAP         0xc023          /* Password Authentication Protocol */
     108             : #define PPP_CHAP        0xc223          /* Challenge-Handshake Auth Protocol */
     109             : #define PPP_IPCP        0x8021          /* Internet Protocol Control Protocol */
     110             : #define PPP_IPV6CP      0x8057          /* IPv6 Control Protocol */
     111             : 
     112             : #define CONF_REQ        1               /* PPP configure request */
     113             : #define CONF_ACK        2               /* PPP configure acknowledge */
     114             : #define CONF_NAK        3               /* PPP configure negative ack */
     115             : #define CONF_REJ        4               /* PPP configure reject */
     116             : #define TERM_REQ        5               /* PPP terminate request */
     117             : #define TERM_ACK        6               /* PPP terminate acknowledge */
     118             : #define CODE_REJ        7               /* PPP code reject */
     119             : #define PROTO_REJ       8               /* PPP protocol reject */
     120             : #define ECHO_REQ        9               /* PPP echo request */
     121             : #define ECHO_REPLY      10              /* PPP echo reply */
     122             : #define DISC_REQ        11              /* PPP discard request */
     123             : 
     124             : #define LCP_OPT_MRU             1       /* maximum receive unit */
     125             : #define LCP_OPT_ASYNC_MAP       2       /* async control character map */
     126             : #define LCP_OPT_AUTH_PROTO      3       /* authentication protocol */
     127             : #define LCP_OPT_QUAL_PROTO      4       /* quality protocol */
     128             : #define LCP_OPT_MAGIC           5       /* magic number */
     129             : #define LCP_OPT_RESERVED        6       /* reserved */
     130             : #define LCP_OPT_PROTO_COMP      7       /* protocol field compression */
     131             : #define LCP_OPT_ADDR_COMP       8       /* address/control field compression */
     132             : 
     133             : #define IPCP_OPT_ADDRESSES      1       /* both IP addresses; deprecated */
     134             : #define IPCP_OPT_COMPRESSION    2       /* IP compression protocol (VJ) */
     135             : #define IPCP_OPT_ADDRESS        3       /* local IP address */
     136             : 
     137             : #define IPV6CP_OPT_IFID         1       /* interface identifier */
     138             : #define IPV6CP_OPT_COMPRESSION  2       /* IPv6 compression protocol */
     139             : 
     140             : #define PAP_REQ                 1       /* PAP name/password request */
     141             : #define PAP_ACK                 2       /* PAP acknowledge */
     142             : #define PAP_NAK                 3       /* PAP fail */
     143             : 
     144             : #define CHAP_CHALLENGE          1       /* CHAP challenge request */
     145             : #define CHAP_RESPONSE           2       /* CHAP challenge response */
     146             : #define CHAP_SUCCESS            3       /* CHAP response ok */
     147             : #define CHAP_FAILURE            4       /* CHAP response failed */
     148             : 
     149             : #define CHAP_MD5                5       /* hash algorithm - MD5 */
     150             : 
     151             : /* states are named and numbered according to RFC 1661 */
     152             : #define STATE_INITIAL   0
     153             : #define STATE_STARTING  1
     154             : #define STATE_CLOSED    2
     155             : #define STATE_STOPPED   3
     156             : #define STATE_CLOSING   4
     157             : #define STATE_STOPPING  5
     158             : #define STATE_REQ_SENT  6
     159             : #define STATE_ACK_RCVD  7
     160             : #define STATE_ACK_SENT  8
     161             : #define STATE_OPENED    9
     162             : 
     163             : #define PKTHDRLEN       2
     164             : 
     165             : struct ppp_header {
     166             :         u_char address;
     167             :         u_char control;
     168             :         u_short protocol;
     169             : };
     170             : #define PPP_HEADER_LEN          sizeof (struct ppp_header)
     171             : 
     172             : struct lcp_header {
     173             :         u_char type;
     174             :         u_char ident;
     175             :         u_short len;
     176             : };
     177             : #define LCP_HEADER_LEN          sizeof (struct lcp_header)
     178             : 
     179             : /*
     180             :  * We follow the spelling and capitalization of RFC 1661 here, to make
     181             :  * it easier comparing with the standard.  Please refer to this RFC in
     182             :  * case you can't make sense out of these abbreviation; it will also
     183             :  * explain the semantics related to the various events and actions.
     184             :  */
     185             : struct cp {
     186             :         u_short proto;          /* PPP control protocol number */
     187             :         u_char protoidx;        /* index into state table in struct sppp */
     188             :         u_char flags;
     189             : #define CP_LCP          0x01    /* this is the LCP */
     190             : #define CP_AUTH         0x02    /* this is an authentication protocol */
     191             : #define CP_NCP          0x04    /* this is a NCP */
     192             : #define CP_QUAL         0x08    /* this is a quality reporting protocol */
     193             :         const char *name;       /* name of this control protocol */
     194             :         /* event handlers */
     195             :         void    (*Up)(struct sppp *sp);
     196             :         void    (*Down)(struct sppp *sp);
     197             :         void    (*Open)(struct sppp *sp);
     198             :         void    (*Close)(struct sppp *sp);
     199             :         void    (*TO)(void *sp);
     200             :         int     (*RCR)(struct sppp *sp, struct lcp_header *h, int len);
     201             :         void    (*RCN_rej)(struct sppp *sp, struct lcp_header *h, int len);
     202             :         void    (*RCN_nak)(struct sppp *sp, struct lcp_header *h, int len);
     203             :         /* actions */
     204             :         void    (*tlu)(struct sppp *sp);
     205             :         void    (*tld)(struct sppp *sp);
     206             :         void    (*tls)(struct sppp *sp);
     207             :         void    (*tlf)(struct sppp *sp);
     208             :         void    (*scr)(struct sppp *sp);
     209             : };
     210             : 
     211             : static struct sppp *spppq;
     212             : static struct timeout keepalive_ch;
     213             : 
     214             : #define SPP_FMT         "%s: "
     215             : #define SPP_ARGS(ifp)   (ifp)->if_xname
     216             : 
     217             : /* almost every function needs these */
     218             : #define STDDCL                                                  \
     219             :         struct ifnet *ifp = &sp->pp_if;                          \
     220             :         int debug = ifp->if_flags & IFF_DEBUG
     221             : 
     222             : int sppp_output(struct ifnet *ifp, struct mbuf *m,
     223             :                        struct sockaddr *dst, struct rtentry *rt);
     224             : 
     225             : void sppp_cp_input(const struct cp *cp, struct sppp *sp,
     226             :                           struct mbuf *m);
     227             : void sppp_cp_send(struct sppp *sp, u_short proto, u_char type,
     228             :                          u_char ident, u_short len, void *data);
     229             : #ifdef notyet
     230             : void sppp_cp_timeout(void *arg);
     231             : #endif
     232             : void sppp_cp_change_state(const struct cp *cp, struct sppp *sp,
     233             :                                  int newstate);
     234             : void sppp_auth_send(const struct cp *cp,
     235             :                            struct sppp *sp, unsigned int type, u_int id,
     236             :                            ...);
     237             : 
     238             : void sppp_up_event(const struct cp *cp, struct sppp *sp);
     239             : void sppp_down_event(const struct cp *cp, struct sppp *sp);
     240             : void sppp_open_event(const struct cp *cp, struct sppp *sp);
     241             : void sppp_close_event(const struct cp *cp, struct sppp *sp);
     242             : void sppp_increasing_timeout(const struct cp *cp, struct sppp *sp);
     243             : void sppp_to_event(const struct cp *cp, struct sppp *sp);
     244             : 
     245             : void sppp_null(struct sppp *sp);
     246             : 
     247             : void sppp_lcp_init(struct sppp *sp);
     248             : void sppp_lcp_up(struct sppp *sp);
     249             : void sppp_lcp_down(struct sppp *sp);
     250             : void sppp_lcp_open(struct sppp *sp);
     251             : void sppp_lcp_close(struct sppp *sp);
     252             : void sppp_lcp_TO(void *sp);
     253             : int sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len);
     254             : void sppp_lcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len);
     255             : void sppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len);
     256             : void sppp_lcp_tlu(struct sppp *sp);
     257             : void sppp_lcp_tld(struct sppp *sp);
     258             : void sppp_lcp_tls(struct sppp *sp);
     259             : void sppp_lcp_tlf(struct sppp *sp);
     260             : void sppp_lcp_scr(struct sppp *sp);
     261             : void sppp_lcp_check_and_close(struct sppp *sp);
     262             : int sppp_ncp_check(struct sppp *sp);
     263             : 
     264             : void sppp_ipcp_init(struct sppp *sp);
     265             : void sppp_ipcp_destroy(struct sppp *sp);
     266             : void sppp_ipcp_up(struct sppp *sp);
     267             : void sppp_ipcp_down(struct sppp *sp);
     268             : void sppp_ipcp_open(struct sppp *sp);
     269             : void sppp_ipcp_close(struct sppp *sp);
     270             : void sppp_ipcp_TO(void *sp);
     271             : int sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len);
     272             : void sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len);
     273             : void sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len);
     274             : void sppp_ipcp_tlu(struct sppp *sp);
     275             : void sppp_ipcp_tld(struct sppp *sp);
     276             : void sppp_ipcp_tls(struct sppp *sp);
     277             : void sppp_ipcp_tlf(struct sppp *sp);
     278             : void sppp_ipcp_scr(struct sppp *sp);
     279             : 
     280             : void sppp_ipv6cp_init(struct sppp *sp);
     281             : void sppp_ipv6cp_destroy(struct sppp *sp);
     282             : void sppp_ipv6cp_up(struct sppp *sp);
     283             : void sppp_ipv6cp_down(struct sppp *sp);
     284             : void sppp_ipv6cp_open(struct sppp *sp);
     285             : void sppp_ipv6cp_close(struct sppp *sp);
     286             : void sppp_ipv6cp_TO(void *sp);
     287             : int sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len);
     288             : void sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len);
     289             : void sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len);
     290             : void sppp_ipv6cp_tlu(struct sppp *sp);
     291             : void sppp_ipv6cp_tld(struct sppp *sp);
     292             : void sppp_ipv6cp_tls(struct sppp *sp);
     293             : void sppp_ipv6cp_tlf(struct sppp *sp);
     294             : void sppp_ipv6cp_scr(struct sppp *sp);
     295             : const char *sppp_ipv6cp_opt_name(u_char opt);
     296             : void sppp_get_ip6_addrs(struct sppp *sp, struct in6_addr *src,
     297             :                                struct in6_addr *dst, struct in6_addr *srcmask);
     298             : void sppp_set_ip6_addr(struct sppp *sp, const struct in6_addr *src, const struct in6_addr *dst);
     299             : void sppp_update_ip6_addr(void *sp);
     300             : void sppp_suggest_ip6_addr(struct sppp *sp, struct in6_addr *suggest);
     301             : 
     302             : void sppp_pap_input(struct sppp *sp, struct mbuf *m);
     303             : void sppp_pap_init(struct sppp *sp);
     304             : void sppp_pap_open(struct sppp *sp);
     305             : void sppp_pap_close(struct sppp *sp);
     306             : void sppp_pap_TO(void *sp);
     307             : void sppp_pap_my_TO(void *sp);
     308             : void sppp_pap_tlu(struct sppp *sp);
     309             : void sppp_pap_tld(struct sppp *sp);
     310             : void sppp_pap_scr(struct sppp *sp);
     311             : 
     312             : void sppp_chap_input(struct sppp *sp, struct mbuf *m);
     313             : void sppp_chap_init(struct sppp *sp);
     314             : void sppp_chap_open(struct sppp *sp);
     315             : void sppp_chap_close(struct sppp *sp);
     316             : void sppp_chap_TO(void *sp);
     317             : void sppp_chap_tlu(struct sppp *sp);
     318             : void sppp_chap_tld(struct sppp *sp);
     319             : void sppp_chap_scr(struct sppp *sp);
     320             : 
     321             : const char *sppp_auth_type_name(u_short proto, u_char type);
     322             : const char *sppp_cp_type_name(u_char type);
     323             : const char *sppp_dotted_quad(u_int32_t addr);
     324             : const char *sppp_ipcp_opt_name(u_char opt);
     325             : const char *sppp_lcp_opt_name(u_char opt);
     326             : const char *sppp_phase_name(enum ppp_phase phase);
     327             : const char *sppp_proto_name(u_short proto);
     328             : const char *sppp_state_name(int state);
     329             : int sppp_get_params(struct sppp *sp, struct ifreq *data);
     330             : int sppp_set_params(struct sppp *sp, struct ifreq *data);
     331             : void sppp_get_ip_addrs(struct sppp *sp, u_int32_t *src, u_int32_t *dst,
     332             :                               u_int32_t *srcmask);
     333             : void sppp_keepalive(void *dummy);
     334             : void sppp_phase_network(struct sppp *sp);
     335             : void sppp_print_bytes(const u_char *p, u_short len);
     336             : void sppp_print_string(const char *p, u_short len);
     337             : int sppp_update_gw_walker(struct rtentry *rt, void *arg, unsigned int id);
     338             : void sppp_update_gw(struct ifnet *ifp);
     339             : void sppp_set_ip_addrs(void *);
     340             : void sppp_clear_ip_addrs(void *);
     341             : void sppp_set_phase(struct sppp *sp);
     342             : 
     343             : /* our control protocol descriptors */
     344             : static const struct cp lcp = {
     345             :         PPP_LCP, IDX_LCP, CP_LCP, "lcp",
     346             :         sppp_lcp_up, sppp_lcp_down, sppp_lcp_open, sppp_lcp_close,
     347             :         sppp_lcp_TO, sppp_lcp_RCR, sppp_lcp_RCN_rej, sppp_lcp_RCN_nak,
     348             :         sppp_lcp_tlu, sppp_lcp_tld, sppp_lcp_tls, sppp_lcp_tlf,
     349             :         sppp_lcp_scr
     350             : };
     351             : 
     352             : static const struct cp ipcp = {
     353             :         PPP_IPCP, IDX_IPCP,
     354             :         CP_NCP,
     355             :         "ipcp",
     356             :         sppp_ipcp_up, sppp_ipcp_down, sppp_ipcp_open, sppp_ipcp_close,
     357             :         sppp_ipcp_TO, sppp_ipcp_RCR, sppp_ipcp_RCN_rej, sppp_ipcp_RCN_nak,
     358             :         sppp_ipcp_tlu, sppp_ipcp_tld, sppp_ipcp_tls, sppp_ipcp_tlf,
     359             :         sppp_ipcp_scr
     360             : };
     361             : 
     362             : static const struct cp ipv6cp = {
     363             :         PPP_IPV6CP, IDX_IPV6CP,
     364             : #ifdef INET6    /*don't run IPv6CP if there's no IPv6 support*/
     365             :         CP_NCP,
     366             : #else
     367             :         0,
     368             : #endif
     369             :         "ipv6cp",
     370             :         sppp_ipv6cp_up, sppp_ipv6cp_down, sppp_ipv6cp_open, sppp_ipv6cp_close,
     371             :         sppp_ipv6cp_TO, sppp_ipv6cp_RCR, sppp_ipv6cp_RCN_rej, sppp_ipv6cp_RCN_nak,
     372             :         sppp_ipv6cp_tlu, sppp_ipv6cp_tld, sppp_ipv6cp_tls, sppp_ipv6cp_tlf,
     373             :         sppp_ipv6cp_scr
     374             : };
     375             : 
     376             : static const struct cp pap = {
     377             :         PPP_PAP, IDX_PAP, CP_AUTH, "pap",
     378             :         sppp_null, sppp_null, sppp_pap_open, sppp_pap_close,
     379             :         sppp_pap_TO, 0, 0, 0,
     380             :         sppp_pap_tlu, sppp_pap_tld, sppp_null, sppp_null,
     381             :         sppp_pap_scr
     382             : };
     383             : 
     384             : static const struct cp chap = {
     385             :         PPP_CHAP, IDX_CHAP, CP_AUTH, "chap",
     386             :         sppp_null, sppp_null, sppp_chap_open, sppp_chap_close,
     387             :         sppp_chap_TO, 0, 0, 0,
     388             :         sppp_chap_tlu, sppp_chap_tld, sppp_null, sppp_null,
     389             :         sppp_chap_scr
     390             : };
     391             : 
     392             : static const struct cp *cps[IDX_COUNT] = {
     393             :         &lcp,                       /* IDX_LCP */
     394             :         &ipcp,                      /* IDX_IPCP */
     395             :         &ipv6cp,            /* IDX_IPV6CP */
     396             :         &pap,                       /* IDX_PAP */
     397             :         &chap,                      /* IDX_CHAP */
     398             : };
     399             : 
     400             : 
     401             : /*
     402             :  * Exported functions, comprising our interface to the lower layer.
     403             :  */
     404             : 
     405             : /* Workaround */
     406             : void
     407           0 : spppattach(struct ifnet *ifp)
     408             : {
     409           0 : }
     410             : 
     411             : /*
     412             :  * Process the received packet.
     413             :  */
     414             : void
     415           0 : sppp_input(struct ifnet *ifp, struct mbuf *m)
     416             : {
     417           0 :         struct ppp_header ht;
     418           0 :         struct sppp *sp = (struct sppp *)ifp;
     419           0 :         struct timeval tv;
     420           0 :         int debug = ifp->if_flags & IFF_DEBUG;
     421             : 
     422           0 :         getmicrouptime(&tv);
     423             : 
     424           0 :         if (ifp->if_flags & IFF_UP) {
     425             :                 /* Count received bytes, add hardware framing */
     426           0 :                 ifp->if_ibytes += m->m_pkthdr.len + sp->pp_framebytes;
     427             :                 /* Note time of last receive */
     428           0 :                 sp->pp_last_receive = tv.tv_sec;
     429           0 :         }
     430             : 
     431           0 :         if (m->m_pkthdr.len <= PPP_HEADER_LEN) {
     432             :                 /* Too small packet, drop it. */
     433           0 :                 if (debug)
     434           0 :                         log(LOG_DEBUG,
     435             :                             SPP_FMT "input packet is too small, %d bytes\n",
     436           0 :                             SPP_ARGS(ifp), m->m_pkthdr.len);
     437             :           drop:
     438           0 :                 m_freem (m);
     439           0 :                 ++ifp->if_ierrors;
     440           0 :                 ++ifp->if_iqdrops;
     441           0 :                 return;
     442             :         }
     443             : 
     444             :         /* mark incoming routing domain */
     445           0 :         m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
     446             : 
     447           0 :         m_copydata(m, 0, sizeof(ht.protocol), (caddr_t)&ht.protocol);
     448           0 :         m_adj(m, 2);
     449           0 :         ht.control = PPP_UI;
     450           0 :         ht.address = PPP_ALLSTATIONS;
     451             : 
     452             :         /* preserve the alignment */
     453           0 :         if (m->m_len < m->m_pkthdr.len) {
     454           0 :                 m = m_pullup(m, m->m_pkthdr.len);
     455           0 :                 if (m == NULL) {
     456           0 :                         if (debug)
     457           0 :                                 log(LOG_DEBUG,
     458           0 :                                     SPP_FMT "Failed to align packet!\n", SPP_ARGS(ifp));
     459           0 :                         ++ifp->if_ierrors;
     460           0 :                         ++ifp->if_iqdrops;
     461           0 :                         return;
     462             :                 }
     463             :         }
     464             : 
     465           0 :         switch (ht.address) {
     466             :         case PPP_ALLSTATIONS:
     467           0 :                 if (ht.control != PPP_UI)
     468             :                         goto invalid;
     469           0 :                 switch (ntohs (ht.protocol)) {
     470             :                 default:
     471           0 :                         if (sp->state[IDX_LCP] == STATE_OPENED)
     472           0 :                                 sppp_cp_send (sp, PPP_LCP, PROTO_REJ,
     473           0 :                                     ++sp->pp_seq, 2, &ht.protocol);
     474           0 :                         if (debug)
     475           0 :                                 log(LOG_DEBUG,
     476             :                                     SPP_FMT "invalid input protocol "
     477             :                                     "<addr=0x%x ctrl=0x%x proto=0x%x>\n",
     478           0 :                                     SPP_ARGS(ifp),
     479           0 :                                     ht.address, ht.control, ntohs(ht.protocol));
     480           0 :                         ++ifp->if_noproto;
     481           0 :                         goto drop;
     482             :                 case PPP_LCP:
     483           0 :                         sppp_cp_input(&lcp, sp, m);
     484           0 :                         m_freem (m);
     485           0 :                         return;
     486             :                 case PPP_PAP:
     487           0 :                         if (sp->pp_phase >= PHASE_AUTHENTICATE)
     488           0 :                                 sppp_pap_input(sp, m);
     489           0 :                         m_freem (m);
     490           0 :                         return;
     491             :                 case PPP_CHAP:
     492           0 :                         if (sp->pp_phase >= PHASE_AUTHENTICATE)
     493           0 :                                 sppp_chap_input(sp, m);
     494           0 :                         m_freem (m);
     495           0 :                         return;
     496             :                 case PPP_IPCP:
     497           0 :                         if (sp->pp_phase == PHASE_NETWORK)
     498           0 :                                 sppp_cp_input(&ipcp, sp, m);
     499           0 :                         m_freem (m);
     500           0 :                         return;
     501             :                 case PPP_IP:
     502           0 :                         if (sp->state[IDX_IPCP] == STATE_OPENED) {
     503           0 :                                 sp->pp_last_activity = tv.tv_sec;
     504           0 :                                 if (ifp->if_flags & IFF_UP) {
     505           0 :                                         ipv4_input(ifp, m);
     506           0 :                                         return;
     507             :                                 }
     508             :                         }
     509             :                         break;
     510             : #ifdef INET6
     511             :                 case PPP_IPV6CP:
     512           0 :                         if (sp->pp_phase == PHASE_NETWORK)
     513           0 :                                 sppp_cp_input(&ipv6cp, sp, m);
     514           0 :                         m_freem (m);
     515           0 :                         return;
     516             :                 case PPP_IPV6:
     517           0 :                         if (sp->state[IDX_IPV6CP] == STATE_OPENED) {
     518           0 :                                 sp->pp_last_activity = tv.tv_sec;
     519           0 :                                 if (ifp->if_flags & IFF_UP) {
     520           0 :                                         ipv6_input(ifp, m);
     521           0 :                                         return;
     522             :                                 }
     523             :                         }
     524             :                         break;
     525             : #endif
     526             :                 }
     527             :                 break;
     528             :         default:        /* Invalid PPP packet. */
     529             :           invalid:
     530           0 :                 if (debug)
     531           0 :                         log(LOG_DEBUG,
     532             :                             SPP_FMT "invalid input packet "
     533             :                             "<addr=0x%x ctrl=0x%x proto=0x%x>\n",
     534           0 :                             SPP_ARGS(ifp),
     535           0 :                             ht.address, ht.control, ntohs(ht.protocol));
     536             :                 goto drop;
     537             :         }
     538             : 
     539             :         goto drop;
     540           0 : }
     541             : 
     542             : /*
     543             :  * Enqueue transmit packet.
     544             :  */
     545             : int
     546           0 : sppp_output(struct ifnet *ifp, struct mbuf *m,
     547             :             struct sockaddr *dst, struct rtentry *rt)
     548             : {
     549           0 :         struct sppp *sp = (struct sppp*) ifp;
     550           0 :         struct timeval tv;
     551             :         int s, rv = 0;
     552             :         u_int16_t protocol;
     553             : 
     554             : #ifdef DIAGNOSTIC
     555           0 :         if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
     556           0 :                 printf("%s: trying to send packet on wrong domain. "
     557           0 :                     "if %d vs. mbuf %d, AF %d\n", ifp->if_xname,
     558           0 :                     ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid),
     559           0 :                     dst->sa_family);
     560           0 :         }
     561             : #endif
     562             : 
     563           0 :         s = splnet();
     564             : 
     565           0 :         getmicrouptime(&tv);
     566           0 :         sp->pp_last_activity = tv.tv_sec;
     567             : 
     568           0 :         if ((ifp->if_flags & IFF_UP) == 0 ||
     569           0 :             (ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == 0) {
     570           0 :                 m_freem (m);
     571           0 :                 splx (s);
     572           0 :                 return (ENETDOWN);
     573             :         }
     574             : 
     575           0 :         if ((ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == IFF_AUTO) {
     576             :                 /*
     577             :                  * Interface is not yet running, but auto-dial.  Need
     578             :                  * to start LCP for it.
     579             :                  */
     580           0 :                 ifp->if_flags |= IFF_RUNNING;
     581           0 :                 splx(s);
     582           0 :                 lcp.Open(sp);
     583           0 :                 s = splnet();
     584           0 :         }
     585             : 
     586           0 :         if (dst->sa_family == AF_INET) {
     587             :                 struct ip *ip = NULL;
     588             : 
     589           0 :                 if (m->m_len >= sizeof(struct ip))
     590           0 :                         ip = mtod(m, struct ip *);
     591             : 
     592             :                 /*
     593             :                  * When using dynamic local IP address assignment by using
     594             :                  * 0.0.0.0 as a local address, the first TCP session will
     595             :                  * not connect because the local TCP checksum is computed
     596             :                  * using 0.0.0.0 which will later become our real IP address
     597             :                  * so the TCP checksum computed at the remote end will
     598             :                  * become invalid. So we
     599             :                  * - don't let packets with src ip addr 0 thru
     600             :                  * - we flag TCP packets with src ip 0 as an error
     601             :                  */
     602             : 
     603           0 :                 if (ip && ip->ip_src.s_addr == INADDR_ANY) {
     604           0 :                         u_int8_t proto = ip->ip_p;
     605             : 
     606           0 :                         m_freem(m);
     607           0 :                         splx(s);
     608           0 :                         if (proto == IPPROTO_TCP)
     609           0 :                                 return (EADDRNOTAVAIL);
     610             :                         else
     611           0 :                                 return (0);
     612             :                 }
     613           0 :         }
     614             : 
     615           0 :         switch (dst->sa_family) {
     616             :         case AF_INET:   /* Internet Protocol */
     617             :                 /*
     618             :                  * Don't choke with an ENETDOWN early.  It's
     619             :                  * possible that we just started dialing out,
     620             :                  * so don't drop the packet immediately.  If
     621             :                  * we notice that we run out of buffer space
     622             :                  * below, we will however remember that we are
     623             :                  * not ready to carry IP packets, and return
     624             :                  * ENETDOWN, as opposed to ENOBUFS.
     625             :                  */
     626             :                 protocol = htons(PPP_IP);
     627           0 :                 if (sp->state[IDX_IPCP] != STATE_OPENED)
     628           0 :                         rv = ENETDOWN;
     629             :                 break;
     630             : #ifdef INET6
     631             :         case AF_INET6:   /* Internet Protocol v6 */
     632             :                 /*
     633             :                  * Don't choke with an ENETDOWN early.  It's
     634             :                  * possible that we just started dialing out,
     635             :                  * so don't drop the packet immediately.  If
     636             :                  * we notice that we run out of buffer space
     637             :                  * below, we will however remember that we are
     638             :                  * not ready to carry IPv6 packets, and return
     639             :                  * ENETDOWN, as opposed to ENOBUFS.
     640             :                  */
     641             :                 protocol = htons(PPP_IPV6);
     642           0 :                 if (sp->state[IDX_IPV6CP] != STATE_OPENED)
     643           0 :                         rv = ENETDOWN;
     644             :                 break;
     645             : #endif
     646             :         default:
     647           0 :                 m_freem(m);
     648           0 :                 ++ifp->if_oerrors;
     649           0 :                 splx(s);
     650           0 :                 return (EAFNOSUPPORT);
     651             :         }
     652             : 
     653           0 :         M_PREPEND(m, 2, M_DONTWAIT);
     654           0 :         if (m == NULL) {
     655           0 :                 if (ifp->if_flags & IFF_DEBUG)
     656           0 :                         log(LOG_DEBUG, SPP_FMT
     657             :                             "no memory for transmit header\n",
     658           0 :                             SPP_ARGS(ifp));
     659           0 :                 ++ifp->if_oerrors;
     660           0 :                 splx(s);
     661           0 :                 return (rv ? rv : ENOBUFS);
     662             :         }
     663           0 :         *mtod(m, u_int16_t *) = protocol;
     664             : 
     665             :         /*
     666             :          * Queue message on interface, and start output if interface
     667             :          * not yet active.
     668             :          */
     669           0 :         rv = if_enqueue(ifp, m);
     670           0 :         if (rv != 0) {
     671           0 :                 ifp->if_oerrors++;
     672           0 :                 splx(s);
     673           0 :                 return (rv);
     674             :         }
     675             : 
     676             :         /*
     677             :          * Count output packets and bytes.
     678             :          * The packet length includes header, FCS and 1 flag,
     679             :          * according to RFC 1333.
     680             :          */
     681           0 :         ifp->if_obytes += sp->pp_framebytes;
     682           0 :         splx(s);
     683             : 
     684           0 :         return (0);
     685           0 : }
     686             : 
     687             : void
     688           0 : sppp_attach(struct ifnet *ifp)
     689             : {
     690           0 :         struct sppp *sp = (struct sppp*) ifp;
     691             :         int i;
     692             : 
     693             :         /* Initialize keepalive handler. */
     694           0 :         if (! spppq) {
     695           0 :                 timeout_set_proc(&keepalive_ch, sppp_keepalive, NULL);
     696           0 :                 timeout_add_sec(&keepalive_ch, 10);
     697           0 :         }
     698             : 
     699             :         /* Insert new entry into the keepalive list. */
     700           0 :         sp->pp_next = spppq;
     701           0 :         spppq = sp;
     702             : 
     703           0 :         sp->pp_if.if_type = IFT_PPP;
     704           0 :         sp->pp_if.if_output = sppp_output;
     705           0 :         IFQ_SET_MAXLEN(&sp->pp_if.if_snd, 50);
     706           0 :         mq_init(&sp->pp_cpq, 50, IPL_NET);
     707           0 :         sp->pp_loopcnt = 0;
     708           0 :         sp->pp_alivecnt = 0;
     709           0 :         sp->pp_last_activity = 0;
     710           0 :         sp->pp_last_receive = 0;
     711           0 :         sp->pp_seq = 0;
     712           0 :         sp->pp_rseq = 0;
     713           0 :         sp->pp_phase = PHASE_DEAD;
     714           0 :         sp->pp_up = lcp.Up;
     715           0 :         sp->pp_down = lcp.Down;
     716             : 
     717           0 :         for (i = 0; i < IDX_COUNT; i++)
     718           0 :                 timeout_set(&sp->ch[i], (cps[i])->TO, (void *)sp);
     719           0 :         timeout_set(&sp->pap_my_to_ch, sppp_pap_my_TO, (void *)sp);
     720             : 
     721           0 :         sppp_lcp_init(sp);
     722           0 :         sppp_ipcp_init(sp);
     723           0 :         sppp_ipv6cp_init(sp);
     724           0 :         sppp_pap_init(sp);
     725           0 :         sppp_chap_init(sp);
     726           0 : }
     727             : 
     728             : void
     729           0 : sppp_detach(struct ifnet *ifp)
     730             : {
     731           0 :         struct sppp **q, *p, *sp = (struct sppp*) ifp;
     732             :         int i;
     733             : 
     734           0 :         sppp_ipcp_destroy(sp);
     735           0 :         sppp_ipv6cp_destroy(sp);
     736             : 
     737             :         /* Remove the entry from the keepalive list. */
     738           0 :         for (q = &spppq; (p = *q); q = &p->pp_next)
     739           0 :                 if (p == sp) {
     740           0 :                         *q = p->pp_next;
     741           0 :                         break;
     742             :                 }
     743             : 
     744             :         /* Stop keepalive handler. */
     745           0 :         if (! spppq)
     746           0 :                 UNTIMEOUT(sppp_keepalive, 0, keepalive_ch);
     747             : 
     748           0 :         for (i = 0; i < IDX_COUNT; i++)
     749           0 :                 UNTIMEOUT((cps[i])->TO, (void *)sp, sp->ch[i]);
     750           0 :         UNTIMEOUT(sppp_pap_my_TO, (void *)sp, sp->pap_my_to_ch);
     751             : 
     752             :         /* release authentication data */
     753           0 :         if (sp->myauth.name != NULL)
     754           0 :                 free(sp->myauth.name, M_DEVBUF, 0);
     755           0 :         if (sp->myauth.secret != NULL)
     756           0 :                 free(sp->myauth.secret, M_DEVBUF, 0);
     757           0 :         if (sp->hisauth.name != NULL)
     758           0 :                 free(sp->hisauth.name, M_DEVBUF, 0);
     759           0 :         if (sp->hisauth.secret != NULL)
     760           0 :                 free(sp->hisauth.secret, M_DEVBUF, 0);
     761           0 : }
     762             : 
     763             : /*
     764             :  * Flush the interface output queue.
     765             :  */
     766             : void
     767           0 : sppp_flush(struct ifnet *ifp)
     768             : {
     769           0 :         struct sppp *sp = (struct sppp*) ifp;
     770             : 
     771           0 :         IFQ_PURGE(&sp->pp_if.if_snd);
     772           0 :         mq_purge(&sp->pp_cpq);
     773           0 : }
     774             : 
     775             : /*
     776             :  * Check if the output queue is empty.
     777             :  */
     778             : int
     779           0 : sppp_isempty(struct ifnet *ifp)
     780             : {
     781           0 :         struct sppp *sp = (struct sppp*) ifp;
     782             :         int empty, s;
     783             : 
     784           0 :         s = splnet();
     785           0 :         empty = mq_empty(&sp->pp_cpq) && IFQ_IS_EMPTY(&sp->pp_if.if_snd);
     786           0 :         splx(s);
     787           0 :         return (empty);
     788             : }
     789             : 
     790             : /*
     791             :  * Get next packet to send.
     792             :  */
     793             : struct mbuf *
     794           0 : sppp_dequeue(struct ifnet *ifp)
     795             : {
     796           0 :         struct sppp *sp = (struct sppp*) ifp;
     797             :         struct mbuf *m;
     798             :         int s;
     799             : 
     800           0 :         s = splnet();
     801             :         /*
     802             :          * Process only the control protocol queue until we have at
     803             :          * least one NCP open.
     804             :          */
     805           0 :         m = mq_dequeue(&sp->pp_cpq);
     806           0 :         if (m == NULL && sppp_ncp_check(sp)) {
     807           0 :                 IFQ_DEQUEUE (&sp->pp_if.if_snd, m);
     808           0 :         }
     809           0 :         splx(s);
     810           0 :         return m;
     811             : }
     812             : 
     813             : /*
     814             :  * Process an ioctl request.  Called on low priority level.
     815             :  */
     816             : int
     817           0 : sppp_ioctl(struct ifnet *ifp, u_long cmd, void *data)
     818             : {
     819           0 :         struct ifreq *ifr = data;
     820           0 :         struct sppp *sp = (struct sppp*) ifp;
     821             :         int s, rv, going_up, going_down, newmode;
     822             : 
     823           0 :         s = splnet();
     824             :         rv = 0;
     825           0 :         switch (cmd) {
     826             :         case SIOCSIFDSTADDR:
     827             :                 break;
     828             : 
     829             :         case SIOCSIFADDR:
     830           0 :                 if_up(ifp);
     831             :                 /* FALLTHROUGH */
     832             : 
     833             :         case SIOCSIFFLAGS:
     834           0 :                 going_up = (ifp->if_flags & IFF_UP) &&
     835           0 :                         (ifp->if_flags & IFF_RUNNING) == 0;
     836           0 :                 going_down = (ifp->if_flags & IFF_UP) == 0 &&
     837           0 :                         (ifp->if_flags & IFF_RUNNING);
     838           0 :                 newmode = ifp->if_flags & (IFF_AUTO | IFF_PASSIVE);
     839           0 :                 if (newmode == (IFF_AUTO | IFF_PASSIVE)) {
     840             :                         /* sanity */
     841             :                         newmode = IFF_PASSIVE;
     842           0 :                         ifp->if_flags &= ~IFF_AUTO;
     843           0 :                 }
     844             : 
     845           0 :                 if (going_up || going_down)
     846           0 :                         lcp.Close(sp);
     847             : 
     848           0 :                 if (going_up && newmode == 0) {
     849             :                         /* neither auto-dial nor passive */
     850           0 :                         ifp->if_flags |= IFF_RUNNING;
     851           0 :                         lcp.Open(sp);
     852           0 :                 } else if (going_down) {
     853           0 :                         sppp_flush(ifp);
     854           0 :                         ifp->if_flags &= ~IFF_RUNNING;
     855           0 :                 }
     856             :                 break;
     857             : 
     858             :         case SIOCSIFMTU:
     859           0 :                 if (ifr->ifr_mtu < 128 ||
     860           0 :                     (sp->lcp.their_mru > 0 &&
     861           0 :                      ifr->ifr_mtu > sp->lcp.their_mru)) {
     862           0 :                         splx(s);
     863           0 :                         return (EINVAL);
     864             :                 }
     865           0 :                 ifp->if_mtu = ifr->ifr_mtu;
     866           0 :                 break;
     867             :         case SIOCADDMULTI:
     868             :         case SIOCDELMULTI:
     869             :                 break;
     870             : 
     871             :         case SIOCGSPPPPARAMS:
     872           0 :                 rv = sppp_get_params(sp, ifr);
     873           0 :                 break;
     874             : 
     875             :         case SIOCSSPPPPARAMS:
     876           0 :                 rv = sppp_set_params(sp, ifr);
     877           0 :                 break;
     878             : 
     879             :         default:
     880             :                 rv = ENOTTY;
     881           0 :         }
     882           0 :         splx(s);
     883           0 :         return rv;
     884           0 : }
     885             : 
     886             : /*
     887             :  * PPP protocol implementation.
     888             :  */
     889             : 
     890             : /*
     891             :  * Send PPP control protocol packet.
     892             :  */
     893             : void
     894           0 : sppp_cp_send(struct sppp *sp, u_short proto, u_char type,
     895             :              u_char ident, u_short len, void *data)
     896             : {
     897           0 :         STDDCL;
     898             :         int s;
     899             :         struct lcp_header *lh;
     900             :         struct mbuf *m;
     901             : 
     902           0 :         if (len > MHLEN - PKTHDRLEN - LCP_HEADER_LEN)
     903           0 :                 len = MHLEN - PKTHDRLEN - LCP_HEADER_LEN;
     904           0 :         MGETHDR (m, M_DONTWAIT, MT_DATA);
     905           0 :         if (! m)
     906           0 :                 return;
     907           0 :         m->m_pkthdr.len = m->m_len = PKTHDRLEN + LCP_HEADER_LEN + len;
     908           0 :         m->m_pkthdr.ph_ifidx = 0;
     909           0 :         m->m_pkthdr.pf.prio = sp->pp_if.if_llprio;
     910             : 
     911           0 :         *mtod(m, u_int16_t *) = htons(proto);
     912           0 :         lh = (struct lcp_header *)(mtod(m, u_int8_t *) + 2);
     913           0 :         lh->type = type;
     914           0 :         lh->ident = ident;
     915           0 :         lh->len = htons (LCP_HEADER_LEN + len);
     916           0 :         if (len)
     917           0 :                 bcopy (data, lh+1, len);
     918             : 
     919           0 :         if (debug) {
     920           0 :                 log(LOG_DEBUG, SPP_FMT "%s output <%s id=0x%x len=%d",
     921           0 :                     SPP_ARGS(ifp),
     922           0 :                     sppp_proto_name(proto),
     923           0 :                     sppp_cp_type_name (lh->type), lh->ident,
     924           0 :                     ntohs (lh->len));
     925           0 :                 if (len)
     926           0 :                         sppp_print_bytes ((u_char*) (lh+1), len);
     927           0 :                 addlog(">\n");
     928           0 :         }
     929             : 
     930           0 :         len = m->m_pkthdr.len + sp->pp_framebytes;
     931           0 :         if (mq_enqueue(&sp->pp_cpq, m) != 0) {
     932           0 :                 ifp->if_oerrors++;
     933           0 :                 return;
     934             :         }
     935             : 
     936           0 :         ifp->if_obytes += len;
     937           0 :         s = splnet();
     938           0 :         if_start(ifp);
     939           0 :         splx(s);
     940           0 : }
     941             : 
     942             : /*
     943             :  * Handle incoming PPP control protocol packets.
     944             :  */
     945             : void
     946           0 : sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m)
     947             : {
     948           0 :         STDDCL;
     949             :         struct lcp_header *h;
     950           0 :         int len = m->m_pkthdr.len;
     951             :         int rv;
     952             :         u_char *p;
     953             :         u_long nmagic;
     954             : 
     955           0 :         if (len < 4) {
     956           0 :                 if (debug)
     957           0 :                         log(LOG_DEBUG,
     958             :                             SPP_FMT "%s invalid packet length: %d bytes\n",
     959           0 :                             SPP_ARGS(ifp), cp->name, len);
     960           0 :                 return;
     961             :         }
     962           0 :         h = mtod (m, struct lcp_header*);
     963           0 :         if (debug) {
     964           0 :                 log(LOG_DEBUG,
     965             :                     SPP_FMT "%s input(%s): <%s id=0x%x len=%d",
     966           0 :                     SPP_ARGS(ifp), cp->name,
     967           0 :                     sppp_state_name(sp->state[cp->protoidx]),
     968           0 :                     sppp_cp_type_name (h->type), h->ident, ntohs (h->len));
     969           0 :                 if (len > 4)
     970           0 :                         sppp_print_bytes ((u_char*) (h+1), len-4);
     971           0 :                 addlog(">\n");
     972           0 :         }
     973           0 :         if (len > ntohs (h->len))
     974           0 :                 len = ntohs (h->len);
     975           0 :         p = (u_char *)(h + 1);
     976           0 :         switch (h->type) {
     977             :         case CONF_REQ:
     978           0 :                 if (len < 4) {
     979           0 :                         if (debug)
     980           0 :                                 addlog(SPP_FMT "%s invalid conf-req length %d\n",
     981           0 :                                        SPP_ARGS(ifp), cp->name,
     982             :                                        len);
     983           0 :                         ++ifp->if_ierrors;
     984           0 :                         break;
     985             :                 }
     986             :                 /* handle states where RCR doesn't get a SCA/SCN */
     987           0 :                 switch (sp->state[cp->protoidx]) {
     988             :                 case STATE_CLOSING:
     989             :                 case STATE_STOPPING:
     990           0 :                         return;
     991             :                 case STATE_CLOSED:
     992           0 :                         sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident,
     993             :                                      0, 0);
     994           0 :                         return;
     995             :                 }
     996           0 :                 rv = (cp->RCR)(sp, h, len);
     997             :                 /* silently drop illegal packets */
     998           0 :                 if (rv == -1)
     999           0 :                         return;
    1000           0 :                 switch (sp->state[cp->protoidx]) {
    1001             :                 case STATE_OPENED:
    1002           0 :                         sppp_cp_change_state(cp, sp, rv?
    1003             :                                              STATE_ACK_SENT: STATE_REQ_SENT);
    1004           0 :                         (cp->tld)(sp);
    1005           0 :                         (cp->scr)(sp);
    1006           0 :                         break;
    1007             :                 case STATE_ACK_SENT:
    1008             :                 case STATE_REQ_SENT:
    1009           0 :                         sppp_cp_change_state(cp, sp, rv?
    1010             :                                              STATE_ACK_SENT: STATE_REQ_SENT);
    1011           0 :                         break;
    1012             :                 case STATE_STOPPED:
    1013           0 :                         sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
    1014           0 :                         sppp_cp_change_state(cp, sp, rv?
    1015             :                                              STATE_ACK_SENT: STATE_REQ_SENT);
    1016           0 :                         (cp->scr)(sp);
    1017           0 :                         break;
    1018             :                 case STATE_ACK_RCVD:
    1019           0 :                         if (rv) {
    1020           0 :                                 sppp_cp_change_state(cp, sp, STATE_OPENED);
    1021           0 :                                 if (debug)
    1022           0 :                                         log(LOG_DEBUG, SPP_FMT "%s tlu\n",
    1023           0 :                                             SPP_ARGS(ifp),
    1024           0 :                                             cp->name);
    1025           0 :                                 (cp->tlu)(sp);
    1026           0 :                         } else
    1027           0 :                                 sppp_cp_change_state(cp, sp, STATE_ACK_RCVD);
    1028             :                         break;
    1029             :                 default:
    1030             :                         /* printf(SPP_FMT "%s illegal %s in state %s\n",
    1031             :                                SPP_ARGS(ifp), cp->name,
    1032             :                                sppp_cp_type_name(h->type),
    1033             :                                sppp_state_name(sp->state[cp->protoidx])); */
    1034           0 :                         ++ifp->if_ierrors;
    1035           0 :                 }
    1036             :                 break;
    1037             :         case CONF_ACK:
    1038           0 :                 if (h->ident != sp->confid[cp->protoidx]) {
    1039           0 :                         if (debug)
    1040           0 :                                 addlog(SPP_FMT "%s id mismatch 0x%x != 0x%x\n",
    1041           0 :                                        SPP_ARGS(ifp), cp->name,
    1042             :                                        h->ident, sp->confid[cp->protoidx]);
    1043           0 :                         ++ifp->if_ierrors;
    1044           0 :                         break;
    1045             :                 }
    1046           0 :                 switch (sp->state[cp->protoidx]) {
    1047             :                 case STATE_CLOSED:
    1048             :                 case STATE_STOPPED:
    1049           0 :                         sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0);
    1050           0 :                         break;
    1051             :                 case STATE_CLOSING:
    1052             :                 case STATE_STOPPING:
    1053             :                         break;
    1054             :                 case STATE_REQ_SENT:
    1055           0 :                         sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
    1056           0 :                         sppp_cp_change_state(cp, sp, STATE_ACK_RCVD);
    1057           0 :                         break;
    1058             :                 case STATE_OPENED:
    1059           0 :                         sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
    1060           0 :                         (cp->tld)(sp);
    1061           0 :                         (cp->scr)(sp);
    1062           0 :                         break;
    1063             :                 case STATE_ACK_RCVD:
    1064           0 :                         sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
    1065           0 :                         (cp->scr)(sp);
    1066           0 :                         break;
    1067             :                 case STATE_ACK_SENT:
    1068           0 :                         sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
    1069           0 :                         sppp_cp_change_state(cp, sp, STATE_OPENED);
    1070           0 :                         if (debug)
    1071           0 :                                 log(LOG_DEBUG, SPP_FMT "%s tlu\n",
    1072           0 :                                        SPP_ARGS(ifp), cp->name);
    1073           0 :                         (cp->tlu)(sp);
    1074           0 :                         break;
    1075             :                 default:
    1076             :                         /* printf(SPP_FMT "%s illegal %s in state %s\n",
    1077             :                                SPP_ARGS(ifp), cp->name,
    1078             :                                sppp_cp_type_name(h->type),
    1079             :                                sppp_state_name(sp->state[cp->protoidx])); */
    1080           0 :                         ++ifp->if_ierrors;
    1081           0 :                 }
    1082             :                 break;
    1083             :         case CONF_NAK:
    1084             :         case CONF_REJ:
    1085           0 :                 if (h->ident != sp->confid[cp->protoidx]) {
    1086           0 :                         if (debug)
    1087           0 :                                 addlog(SPP_FMT "%s id mismatch 0x%x != 0x%x\n",
    1088           0 :                                        SPP_ARGS(ifp), cp->name,
    1089             :                                        h->ident, sp->confid[cp->protoidx]);
    1090           0 :                         ++ifp->if_ierrors;
    1091           0 :                         break;
    1092             :                 }
    1093           0 :                 if (h->type == CONF_NAK)
    1094           0 :                         (cp->RCN_nak)(sp, h, len);
    1095             :                 else /* CONF_REJ */
    1096           0 :                         (cp->RCN_rej)(sp, h, len);
    1097             : 
    1098           0 :                 switch (sp->state[cp->protoidx]) {
    1099             :                 case STATE_CLOSED:
    1100             :                 case STATE_STOPPED:
    1101           0 :                         sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0);
    1102           0 :                         break;
    1103             :                 case STATE_REQ_SENT:
    1104             :                 case STATE_ACK_SENT:
    1105           0 :                         sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
    1106           0 :                         (cp->scr)(sp);
    1107           0 :                         break;
    1108             :                 case STATE_OPENED:
    1109           0 :                         sppp_cp_change_state(cp, sp, STATE_ACK_SENT);
    1110           0 :                         (cp->tld)(sp);
    1111           0 :                         (cp->scr)(sp);
    1112           0 :                         break;
    1113             :                 case STATE_ACK_RCVD:
    1114           0 :                         sppp_cp_change_state(cp, sp, STATE_ACK_SENT);
    1115           0 :                         (cp->scr)(sp);
    1116           0 :                         break;
    1117             :                 case STATE_CLOSING:
    1118             :                 case STATE_STOPPING:
    1119             :                         break;
    1120             :                 default:
    1121             :                         /* printf(SPP_FMT "%s illegal %s in state %s\n",
    1122             :                                SPP_ARGS(ifp), cp->name,
    1123             :                                sppp_cp_type_name(h->type),
    1124             :                                sppp_state_name(sp->state[cp->protoidx])); */
    1125           0 :                         ++ifp->if_ierrors;
    1126           0 :                 }
    1127             :                 break;
    1128             : 
    1129             :         case TERM_REQ:
    1130           0 :                 switch (sp->state[cp->protoidx]) {
    1131             :                 case STATE_ACK_RCVD:
    1132             :                 case STATE_ACK_SENT:
    1133           0 :                         sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
    1134             :                         /* FALLTHROUGH */
    1135             :                 case STATE_CLOSED:
    1136             :                 case STATE_STOPPED:
    1137             :                 case STATE_CLOSING:
    1138             :                 case STATE_STOPPING:
    1139             :                 case STATE_REQ_SENT:
    1140             :                   sta:
    1141             :                         /* Send Terminate-Ack packet. */
    1142           0 :                         if (debug)
    1143           0 :                                 log(LOG_DEBUG, SPP_FMT "%s send terminate-ack\n",
    1144           0 :                                     SPP_ARGS(ifp), cp->name);
    1145           0 :                         sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0);
    1146           0 :                         break;
    1147             :                 case STATE_OPENED:
    1148           0 :                         sp->rst_counter[cp->protoidx] = 0;
    1149           0 :                         sppp_cp_change_state(cp, sp, STATE_STOPPING);
    1150           0 :                         (cp->tld)(sp);
    1151           0 :                         goto sta;
    1152             :                         break;
    1153             :                 default:
    1154             :                         /* printf(SPP_FMT "%s illegal %s in state %s\n",
    1155             :                                SPP_ARGS(ifp), cp->name,
    1156             :                                sppp_cp_type_name(h->type),
    1157             :                                sppp_state_name(sp->state[cp->protoidx])); */
    1158           0 :                         ++ifp->if_ierrors;
    1159           0 :                 }
    1160             :                 break;
    1161             :         case TERM_ACK:
    1162           0 :                 switch (sp->state[cp->protoidx]) {
    1163             :                 case STATE_CLOSED:
    1164             :                 case STATE_STOPPED:
    1165             :                 case STATE_REQ_SENT:
    1166             :                 case STATE_ACK_SENT:
    1167             :                         break;
    1168             :                 case STATE_CLOSING:
    1169           0 :                         sppp_cp_change_state(cp, sp, STATE_CLOSED);
    1170           0 :                         (cp->tlf)(sp);
    1171           0 :                         break;
    1172             :                 case STATE_STOPPING:
    1173           0 :                         sppp_cp_change_state(cp, sp, STATE_STOPPED);
    1174           0 :                         (cp->tlf)(sp);
    1175           0 :                         break;
    1176             :                 case STATE_ACK_RCVD:
    1177           0 :                         sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
    1178           0 :                         break;
    1179             :                 case STATE_OPENED:
    1180           0 :                         sppp_cp_change_state(cp, sp, STATE_ACK_RCVD);
    1181           0 :                         (cp->tld)(sp);
    1182           0 :                         (cp->scr)(sp);
    1183           0 :                         break;
    1184             :                 default:
    1185             :                         /* printf(SPP_FMT "%s illegal %s in state %s\n",
    1186             :                                SPP_ARGS(ifp), cp->name,
    1187             :                                sppp_cp_type_name(h->type),
    1188             :                                sppp_state_name(sp->state[cp->protoidx])); */
    1189           0 :                         ++ifp->if_ierrors;
    1190           0 :                 }
    1191             :                 break;
    1192             :         case CODE_REJ:
    1193             :         case PROTO_REJ:
    1194             :             {
    1195             :                 int catastrophic = 0;
    1196             :                 const struct cp *upper = NULL;
    1197             :                 int i;
    1198             :                 u_int16_t proto;
    1199             : 
    1200           0 :                 if (len < 2) {
    1201           0 :                         if (debug)
    1202           0 :                                 log(LOG_DEBUG, SPP_FMT "invalid proto-rej length\n",
    1203           0 :                                        SPP_ARGS(ifp));
    1204           0 :                         ++ifp->if_ierrors;
    1205           0 :                         break;
    1206             :                 }
    1207             : 
    1208           0 :                 proto = ntohs(*((u_int16_t *)p));
    1209           0 :                 for (i = 0; i < IDX_COUNT; i++) {
    1210           0 :                         if (cps[i]->proto == proto) {
    1211             :                                 upper = cps[i];
    1212           0 :                                 break;
    1213             :                         }
    1214             :                 }
    1215           0 :                 if (upper == NULL)
    1216           0 :                         catastrophic++;
    1217             : 
    1218           0 :                 if (catastrophic || debug)
    1219           0 :                         log(catastrophic? LOG_INFO: LOG_DEBUG,
    1220             :                             SPP_FMT "%s: RXJ%c (%s) for proto 0x%x (%s/%s)\n",
    1221           0 :                             SPP_ARGS(ifp), cp->name, catastrophic ? '-' : '+',
    1222           0 :                             sppp_cp_type_name(h->type), proto,
    1223           0 :                             upper ? upper->name : "unknown",
    1224           0 :                             upper ? sppp_state_name(sp->state[upper->protoidx]) : "?");
    1225             : 
    1226             :                 /*
    1227             :                  * if we got RXJ+ against conf-req, the peer does not implement
    1228             :                  * this particular protocol type.  terminate the protocol.
    1229             :                  */
    1230           0 :                 if (upper) {
    1231           0 :                         if (sp->state[upper->protoidx] == STATE_REQ_SENT) {
    1232           0 :                                 upper->Close(sp);
    1233           0 :                                 break;
    1234             :                         }
    1235             :                 }
    1236             : 
    1237             :                 /* XXX catastrophic rejects (RXJ-) aren't handled yet. */
    1238           0 :                 switch (sp->state[cp->protoidx]) {
    1239             :                 case STATE_CLOSED:
    1240             :                 case STATE_STOPPED:
    1241             :                 case STATE_REQ_SENT:
    1242             :                 case STATE_ACK_SENT:
    1243             :                 case STATE_CLOSING:
    1244             :                 case STATE_STOPPING:
    1245             :                 case STATE_OPENED:
    1246             :                         break;
    1247             :                 case STATE_ACK_RCVD:
    1248           0 :                         sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
    1249           0 :                         break;
    1250             :                 default:
    1251             :                         /* printf(SPP_FMT "%s illegal %s in state %s\n",
    1252             :                                SPP_ARGS(ifp), cp->name,
    1253             :                                sppp_cp_type_name(h->type),
    1254             :                                sppp_state_name(sp->state[cp->protoidx])); */
    1255           0 :                         ++ifp->if_ierrors;
    1256           0 :                 }
    1257           0 :                 break;
    1258             :             }
    1259             :         case DISC_REQ:
    1260           0 :                 if (cp->proto != PPP_LCP)
    1261             :                         goto illegal;
    1262             :                 /* Discard the packet. */
    1263             :                 break;
    1264             :         case ECHO_REQ:
    1265           0 :                 if (cp->proto != PPP_LCP)
    1266             :                         goto illegal;
    1267           0 :                 if (sp->state[cp->protoidx] != STATE_OPENED) {
    1268           0 :                         if (debug)
    1269           0 :                                 addlog(SPP_FMT "lcp echo req but lcp closed\n",
    1270           0 :                                        SPP_ARGS(ifp));
    1271           0 :                         ++ifp->if_ierrors;
    1272           0 :                         break;
    1273             :                 }
    1274           0 :                 if (len < 8) {
    1275           0 :                         if (debug)
    1276           0 :                                 addlog(SPP_FMT "invalid lcp echo request "
    1277             :                                        "packet length: %d bytes\n",
    1278           0 :                                        SPP_ARGS(ifp), len);
    1279             :                         break;
    1280             :                 }
    1281             : 
    1282           0 :                 nmagic = (u_long)p[0] << 24 |
    1283           0 :                     (u_long)p[1] << 16 | p[2] << 8 | p[3];
    1284             : 
    1285           0 :                 if (nmagic == sp->lcp.magic) {
    1286             :                         /* Line loopback mode detected. */
    1287           0 :                         log(LOG_INFO, SPP_FMT "loopback\n", SPP_ARGS(ifp));
    1288             :                         /* Shut down the PPP link. */
    1289           0 :                         lcp.Close(sp);
    1290           0 :                         break;
    1291             :                 }
    1292             : 
    1293           0 :                 p[0] = sp->lcp.magic >> 24;
    1294           0 :                 p[1] = sp->lcp.magic >> 16;
    1295           0 :                 p[2] = sp->lcp.magic >> 8;
    1296           0 :                 p[3] = sp->lcp.magic;
    1297             : 
    1298           0 :                 if (debug)
    1299           0 :                         addlog(SPP_FMT "got lcp echo req, sending echo rep\n",
    1300           0 :                                SPP_ARGS(ifp));
    1301           0 :                 sppp_cp_send (sp, PPP_LCP, ECHO_REPLY, h->ident, len-4, h+1);
    1302           0 :                 break;
    1303             :         case ECHO_REPLY:
    1304           0 :                 if (cp->proto != PPP_LCP)
    1305             :                         goto illegal;
    1306           0 :                 if (h->ident != sp->lcp.echoid) {
    1307           0 :                         ++ifp->if_ierrors;
    1308           0 :                         break;
    1309             :                 }
    1310           0 :                 if (len < 8) {
    1311           0 :                         if (debug)
    1312           0 :                                 addlog(SPP_FMT "lcp invalid echo reply "
    1313             :                                        "packet length: %d bytes\n",
    1314           0 :                                        SPP_ARGS(ifp), len);
    1315             :                         break;
    1316             :                 }
    1317           0 :                 if (debug)
    1318           0 :                         addlog(SPP_FMT "lcp got echo rep\n",
    1319           0 :                                SPP_ARGS(ifp));
    1320             : 
    1321           0 :                 nmagic = (u_long)p[0] << 24 |
    1322           0 :                     (u_long)p[1] << 16 | p[2] << 8 | p[3];
    1323             : 
    1324           0 :                 if (nmagic != sp->lcp.magic)
    1325           0 :                         sp->pp_alivecnt = 0;
    1326             :                 break;
    1327             :         default:
    1328             :                 /* Unknown packet type -- send Code-Reject packet. */
    1329             :           illegal:
    1330           0 :                 if (debug)
    1331           0 :                         addlog(SPP_FMT "%s send code-rej for 0x%x\n",
    1332           0 :                                SPP_ARGS(ifp), cp->name, h->type);
    1333           0 :                 sppp_cp_send(sp, cp->proto, CODE_REJ, ++sp->pp_seq,
    1334           0 :                              m->m_pkthdr.len, h);
    1335           0 :                 ++ifp->if_ierrors;
    1336           0 :         }
    1337           0 : }
    1338             : 
    1339             : 
    1340             : /*
    1341             :  * The generic part of all Up/Down/Open/Close/TO event handlers.
    1342             :  * Basically, the state transition handling in the automaton.
    1343             :  */
    1344             : void
    1345           0 : sppp_up_event(const struct cp *cp, struct sppp *sp)
    1346             : {
    1347           0 :         STDDCL;
    1348             : 
    1349           0 :         if (debug)
    1350           0 :                 log(LOG_DEBUG, SPP_FMT "%s up(%s)\n",
    1351           0 :                     SPP_ARGS(ifp), cp->name,
    1352           0 :                     sppp_state_name(sp->state[cp->protoidx]));
    1353             : 
    1354           0 :         switch (sp->state[cp->protoidx]) {
    1355             :         case STATE_INITIAL:
    1356           0 :                 sppp_cp_change_state(cp, sp, STATE_CLOSED);
    1357           0 :                 break;
    1358             :         case STATE_STARTING:
    1359           0 :                 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
    1360           0 :                 sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
    1361           0 :                 (cp->scr)(sp);
    1362           0 :                 break;
    1363             :         default:
    1364             :                 /* printf(SPP_FMT "%s illegal up in state %s\n",
    1365             :                        SPP_ARGS(ifp), cp->name,
    1366             :                        sppp_state_name(sp->state[cp->protoidx])); */
    1367             :                 break;
    1368             :         }
    1369           0 : }
    1370             : 
    1371             : void
    1372           0 : sppp_down_event(const struct cp *cp, struct sppp *sp)
    1373             : {
    1374           0 :         STDDCL;
    1375             : 
    1376           0 :         if (debug)
    1377           0 :                 log(LOG_DEBUG, SPP_FMT "%s down(%s)\n",
    1378           0 :                     SPP_ARGS(ifp), cp->name,
    1379           0 :                     sppp_state_name(sp->state[cp->protoidx]));
    1380             : 
    1381           0 :         switch (sp->state[cp->protoidx]) {
    1382             :         case STATE_CLOSED:
    1383             :         case STATE_CLOSING:
    1384           0 :                 sppp_cp_change_state(cp, sp, STATE_INITIAL);
    1385           0 :                 break;
    1386             :         case STATE_STOPPED:
    1387           0 :                 sppp_cp_change_state(cp, sp, STATE_STARTING);
    1388           0 :                 (cp->tls)(sp);
    1389           0 :                 break;
    1390             :         case STATE_STOPPING:
    1391             :         case STATE_REQ_SENT:
    1392             :         case STATE_ACK_RCVD:
    1393             :         case STATE_ACK_SENT:
    1394           0 :                 sppp_cp_change_state(cp, sp, STATE_STARTING);
    1395           0 :                 break;
    1396             :         case STATE_OPENED:
    1397           0 :                 sppp_cp_change_state(cp, sp, STATE_STARTING);
    1398           0 :                 (cp->tld)(sp);
    1399           0 :                 break;
    1400             :         default:
    1401             :                 /* printf(SPP_FMT "%s illegal down in state %s\n",
    1402             :                        SPP_ARGS(ifp), cp->name,
    1403             :                        sppp_state_name(sp->state[cp->protoidx])); */
    1404             :                 break;
    1405             :         }
    1406           0 : }
    1407             : 
    1408             : 
    1409             : void
    1410           0 : sppp_open_event(const struct cp *cp, struct sppp *sp)
    1411             : {
    1412           0 :         STDDCL;
    1413             : 
    1414           0 :         if (debug)
    1415           0 :                 log(LOG_DEBUG, SPP_FMT "%s open(%s)\n",
    1416           0 :                     SPP_ARGS(ifp), cp->name,
    1417           0 :                     sppp_state_name(sp->state[cp->protoidx]));
    1418             : 
    1419           0 :         switch (sp->state[cp->protoidx]) {
    1420             :         case STATE_INITIAL:
    1421           0 :                 sppp_cp_change_state(cp, sp, STATE_STARTING);
    1422           0 :                 (cp->tls)(sp);
    1423           0 :                 break;
    1424             :         case STATE_STARTING:
    1425             :                 break;
    1426             :         case STATE_CLOSED:
    1427           0 :                 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
    1428           0 :                 sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
    1429           0 :                 (cp->scr)(sp);
    1430           0 :                 break;
    1431             :         case STATE_STOPPED:
    1432             :         case STATE_STOPPING:
    1433             :         case STATE_REQ_SENT:
    1434             :         case STATE_ACK_RCVD:
    1435             :         case STATE_ACK_SENT:
    1436             :         case STATE_OPENED:
    1437             :                 break;
    1438             :         case STATE_CLOSING:
    1439           0 :                 sppp_cp_change_state(cp, sp, STATE_STOPPING);
    1440           0 :                 break;
    1441             :         }
    1442           0 : }
    1443             : 
    1444             : 
    1445             : void
    1446           0 : sppp_close_event(const struct cp *cp, struct sppp *sp)
    1447             : {
    1448           0 :         STDDCL;
    1449             : 
    1450           0 :         if (debug)
    1451           0 :                 log(LOG_DEBUG, SPP_FMT "%s close(%s)\n",
    1452           0 :                     SPP_ARGS(ifp), cp->name,
    1453           0 :                     sppp_state_name(sp->state[cp->protoidx]));
    1454             : 
    1455           0 :         switch (sp->state[cp->protoidx]) {
    1456             :         case STATE_INITIAL:
    1457             :         case STATE_CLOSED:
    1458             :         case STATE_CLOSING:
    1459             :                 break;
    1460             :         case STATE_STARTING:
    1461           0 :                 sppp_cp_change_state(cp, sp, STATE_INITIAL);
    1462           0 :                 (cp->tlf)(sp);
    1463           0 :                 break;
    1464             :         case STATE_STOPPED:
    1465           0 :                 sppp_cp_change_state(cp, sp, STATE_CLOSED);
    1466           0 :                 break;
    1467             :         case STATE_STOPPING:
    1468           0 :                 sppp_cp_change_state(cp, sp, STATE_CLOSING);
    1469           0 :                 break;
    1470             :         case STATE_OPENED:
    1471           0 :                 sppp_cp_change_state(cp, sp, STATE_CLOSING);
    1472           0 :                 sp->rst_counter[cp->protoidx] = sp->lcp.max_terminate;
    1473           0 :                 sppp_cp_send(sp, cp->proto, TERM_REQ, ++sp->pp_seq, 0, 0);
    1474           0 :                 (cp->tld)(sp);
    1475           0 :                 break;
    1476             :         case STATE_REQ_SENT:
    1477             :         case STATE_ACK_RCVD:
    1478             :         case STATE_ACK_SENT:
    1479           0 :                 sp->rst_counter[cp->protoidx] = sp->lcp.max_terminate;
    1480           0 :                 sppp_cp_send(sp, cp->proto, TERM_REQ, ++sp->pp_seq, 0, 0);
    1481           0 :                 sppp_cp_change_state(cp, sp, STATE_CLOSING);
    1482           0 :                 break;
    1483             :         }
    1484           0 : }
    1485             : 
    1486             : void
    1487           0 : sppp_increasing_timeout (const struct cp *cp, struct sppp *sp)
    1488             : {
    1489             :         int timo;
    1490             : 
    1491           0 :         timo = sp->lcp.max_configure - sp->rst_counter[cp->protoidx];
    1492           0 :         if (timo < 1)
    1493             :                 timo = 1;
    1494           0 :         timeout_add(&sp->ch[cp->protoidx], timo * sp->lcp.timeout);
    1495           0 : }
    1496             : 
    1497             : void
    1498           0 : sppp_to_event(const struct cp *cp, struct sppp *sp)
    1499             : {
    1500           0 :         STDDCL;
    1501             :         int s;
    1502             : 
    1503           0 :         s = splnet();
    1504           0 :         if (debug)
    1505           0 :                 log(LOG_DEBUG, SPP_FMT "%s TO(%s) rst_counter = %d\n",
    1506           0 :                     SPP_ARGS(ifp), cp->name,
    1507           0 :                     sppp_state_name(sp->state[cp->protoidx]),
    1508           0 :                     sp->rst_counter[cp->protoidx]);
    1509             : 
    1510           0 :         if (--sp->rst_counter[cp->protoidx] < 0)
    1511             :                 /* TO- event */
    1512           0 :                 switch (sp->state[cp->protoidx]) {
    1513             :                 case STATE_CLOSING:
    1514           0 :                         sppp_cp_change_state(cp, sp, STATE_CLOSED);
    1515           0 :                         (cp->tlf)(sp);
    1516           0 :                         break;
    1517             :                 case STATE_STOPPING:
    1518           0 :                         sppp_cp_change_state(cp, sp, STATE_STOPPED);
    1519           0 :                         (cp->tlf)(sp);
    1520           0 :                         break;
    1521             :                 case STATE_REQ_SENT:
    1522             :                 case STATE_ACK_RCVD:
    1523             :                 case STATE_ACK_SENT:
    1524           0 :                         sppp_cp_change_state(cp, sp, STATE_STOPPED);
    1525           0 :                         (cp->tlf)(sp);
    1526           0 :                         break;
    1527             :                 }
    1528             :         else
    1529             :                 /* TO+ event */
    1530           0 :                 switch (sp->state[cp->protoidx]) {
    1531             :                 case STATE_CLOSING:
    1532             :                 case STATE_STOPPING:
    1533           0 :                         sppp_cp_send(sp, cp->proto, TERM_REQ, ++sp->pp_seq,
    1534             :                                      0, 0);
    1535           0 :                         sppp_increasing_timeout (cp, sp);
    1536           0 :                         break;
    1537             :                 case STATE_REQ_SENT:
    1538             :                 case STATE_ACK_RCVD:
    1539             :                         /* sppp_cp_change_state() will restart the timer */
    1540           0 :                         sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
    1541           0 :                         (cp->scr)(sp);
    1542           0 :                         break;
    1543             :                 case STATE_ACK_SENT:
    1544           0 :                         sppp_increasing_timeout (cp, sp);
    1545           0 :                         (cp->scr)(sp);
    1546           0 :                         break;
    1547             :                 }
    1548             : 
    1549           0 :         splx(s);
    1550           0 : }
    1551             : 
    1552             : /*
    1553             :  * Change the state of a control protocol in the state automaton.
    1554             :  * Takes care of starting/stopping the restart timer.
    1555             :  */
    1556             : void
    1557           0 : sppp_cp_change_state(const struct cp *cp, struct sppp *sp, int newstate)
    1558             : {
    1559           0 :         STDDCL;
    1560             : 
    1561           0 :         if (debug && sp->state[cp->protoidx] != newstate)
    1562           0 :                 log(LOG_DEBUG, SPP_FMT "%s %s->%s\n",
    1563           0 :                     SPP_ARGS(ifp), cp->name,
    1564           0 :                     sppp_state_name(sp->state[cp->protoidx]),
    1565           0 :                     sppp_state_name(newstate));
    1566           0 :         sp->state[cp->protoidx] = newstate;
    1567             : 
    1568           0 :         switch (newstate) {
    1569             :         case STATE_INITIAL:
    1570             :         case STATE_STARTING:
    1571             :         case STATE_CLOSED:
    1572             :         case STATE_STOPPED:
    1573             :         case STATE_OPENED:
    1574           0 :                 UNTIMEOUT(cp->TO, (void *)sp, sp->ch[cp->protoidx]);
    1575           0 :                 break;
    1576             :         case STATE_CLOSING:
    1577             :         case STATE_STOPPING:
    1578             :         case STATE_REQ_SENT:
    1579             :         case STATE_ACK_RCVD:
    1580             :         case STATE_ACK_SENT:
    1581           0 :                 if (!timeout_pending(&sp->ch[cp->protoidx]))
    1582           0 :                         sppp_increasing_timeout (cp, sp);
    1583             :                 break;
    1584             :         }
    1585           0 : }
    1586             : /*
    1587             :  *--------------------------------------------------------------------------*
    1588             :  *                                                                          *
    1589             :  *                         The LCP implementation.                          *
    1590             :  *                                                                          *
    1591             :  *--------------------------------------------------------------------------*
    1592             :  */
    1593             : void
    1594           0 : sppp_lcp_init(struct sppp *sp)
    1595             : {
    1596           0 :         sp->lcp.opts = (1 << LCP_OPT_MAGIC);
    1597           0 :         sp->lcp.magic = 0;
    1598           0 :         sp->state[IDX_LCP] = STATE_INITIAL;
    1599           0 :         sp->fail_counter[IDX_LCP] = 0;
    1600           0 :         sp->lcp.protos = 0;
    1601           0 :         sp->lcp.mru = sp->pp_if.if_mtu;
    1602           0 :         sp->lcp.their_mru = 0;
    1603             : 
    1604             :         /*
    1605             :          * Initialize counters and timeout values.  Note that we don't
    1606             :          * use the 3 seconds suggested in RFC 1661 since we are likely
    1607             :          * running on a fast link.  XXX We should probably implement
    1608             :          * the exponential backoff option.  Note that these values are
    1609             :          * relevant for all control protocols, not just LCP only.
    1610             :          */
    1611           0 :         sp->lcp.timeout = 1 * hz;
    1612           0 :         sp->lcp.max_terminate = 2;
    1613           0 :         sp->lcp.max_configure = 10;
    1614           0 :         sp->lcp.max_failure = 10;
    1615           0 : }
    1616             : 
    1617             : void
    1618           0 : sppp_lcp_up(struct sppp *sp)
    1619             : {
    1620           0 :         STDDCL;
    1621           0 :         struct timeval tv;
    1622             : 
    1623           0 :         sp->pp_alivecnt = 0;
    1624           0 :         sp->lcp.opts = (1 << LCP_OPT_MAGIC);
    1625           0 :         sp->lcp.magic = 0;
    1626           0 :         sp->lcp.protos = 0;
    1627           0 :         if (sp->pp_if.if_mtu != PP_MTU) {
    1628           0 :                 sp->lcp.mru = sp->pp_if.if_mtu;
    1629           0 :                 sp->lcp.opts |= (1 << LCP_OPT_MRU);
    1630           0 :         } else
    1631           0 :                 sp->lcp.mru = PP_MTU;
    1632           0 :         sp->lcp.their_mru = PP_MTU;
    1633             : 
    1634           0 :         getmicrouptime(&tv);
    1635           0 :         sp->pp_last_receive = sp->pp_last_activity = tv.tv_sec;
    1636             : 
    1637             :         /*
    1638             :          * If this interface is passive or dial-on-demand, and we are
    1639             :          * still in Initial state, it means we've got an incoming
    1640             :          * call.  Activate the interface.
    1641             :          */
    1642           0 :         if ((ifp->if_flags & (IFF_AUTO | IFF_PASSIVE)) != 0) {
    1643           0 :                 if (debug)
    1644           0 :                         log(LOG_DEBUG,
    1645           0 :                             SPP_FMT "Up event", SPP_ARGS(ifp));
    1646           0 :                 ifp->if_flags |= IFF_RUNNING;
    1647           0 :                 if (sp->state[IDX_LCP] == STATE_INITIAL) {
    1648           0 :                         if (debug)
    1649           0 :                                 addlog("(incoming call)\n");
    1650           0 :                         sp->pp_flags |= PP_CALLIN;
    1651           0 :                         lcp.Open(sp);
    1652           0 :                 } else if (debug)
    1653           0 :                         addlog("\n");
    1654           0 :         } else if ((ifp->if_flags & (IFF_AUTO | IFF_PASSIVE)) == 0 &&
    1655           0 :                    (sp->state[IDX_LCP] == STATE_INITIAL)) {
    1656           0 :                         ifp->if_flags |= IFF_RUNNING;
    1657           0 :                         lcp.Open(sp);
    1658           0 :         }
    1659             : 
    1660           0 :         sppp_up_event(&lcp, sp);
    1661           0 : }
    1662             : 
    1663             : void
    1664           0 : sppp_lcp_down(struct sppp *sp)
    1665             : {
    1666           0 :         STDDCL;
    1667             : 
    1668           0 :         sppp_down_event(&lcp, sp);
    1669             : 
    1670             :         /*
    1671             :          * If this is neither a dial-on-demand nor a passive
    1672             :          * interface, simulate an ``ifconfig down'' action, so the
    1673             :          * administrator can force a redial by another ``ifconfig
    1674             :          * up''.  XXX For leased line operation, should we immediately
    1675             :          * try to reopen the connection here?
    1676             :          */
    1677           0 :         if ((ifp->if_flags & (IFF_AUTO | IFF_PASSIVE)) == 0) {
    1678           0 :                 if (debug)
    1679           0 :                         log(LOG_DEBUG, SPP_FMT "Down event (carrier loss), "
    1680           0 :                             "taking interface down.", SPP_ARGS(ifp));
    1681           0 :                 if_down(ifp);
    1682           0 :         } else {
    1683           0 :                 if (debug)
    1684           0 :                         log(LOG_DEBUG, SPP_FMT "Down event (carrier loss)\n",
    1685           0 :                             SPP_ARGS(ifp));
    1686             :         }
    1687             : 
    1688           0 :         if (sp->state[IDX_LCP] != STATE_INITIAL)
    1689           0 :                 lcp.Close(sp);
    1690           0 :         sp->lcp.their_mru = 0;
    1691           0 :         sp->pp_flags &= ~PP_CALLIN;
    1692           0 :         ifp->if_flags &= ~IFF_RUNNING;
    1693           0 :         sppp_flush(ifp);
    1694           0 : }
    1695             : 
    1696             : void
    1697           0 : sppp_lcp_open(struct sppp *sp)
    1698             : {
    1699             :         /*
    1700             :          * If we are authenticator, negotiate LCP_AUTH
    1701             :          */
    1702           0 :         if (sp->hisauth.proto != 0)
    1703           0 :                 sp->lcp.opts |= (1 << LCP_OPT_AUTH_PROTO);
    1704             :         else
    1705           0 :                 sp->lcp.opts &= ~(1 << LCP_OPT_AUTH_PROTO);
    1706           0 :         sp->pp_flags &= ~PP_NEEDAUTH;
    1707           0 :         sppp_open_event(&lcp, sp);
    1708           0 : }
    1709             : 
    1710             : void
    1711           0 : sppp_lcp_close(struct sppp *sp)
    1712             : {
    1713           0 :         sppp_close_event(&lcp, sp);
    1714           0 : }
    1715             : 
    1716             : void
    1717           0 : sppp_lcp_TO(void *cookie)
    1718             : {
    1719           0 :         sppp_to_event(&lcp, (struct sppp *)cookie);
    1720           0 : }
    1721             : 
    1722             : /*
    1723             :  * Analyze a configure request.  Return true if it was agreeable, and
    1724             :  * caused action sca, false if it has been rejected or nak'ed, and
    1725             :  * caused action scn.  (The return value is used to make the state
    1726             :  * transition decision in the state automaton.)
    1727             :  */
    1728             : int
    1729           0 : sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len)
    1730             : {
    1731           0 :         STDDCL;
    1732             :         u_char *buf, *r, *p;
    1733             :         int origlen, rlen;
    1734             :         u_long nmagic;
    1735             :         u_short authproto;
    1736             : 
    1737           0 :         len -= 4;
    1738             :         origlen = len;
    1739           0 :         buf = r = malloc (len, M_TEMP, M_NOWAIT);
    1740           0 :         if (! buf)
    1741           0 :                 return (0);
    1742             : 
    1743           0 :         if (debug)
    1744           0 :                 log(LOG_DEBUG, SPP_FMT "lcp parse opts: ",
    1745           0 :                     SPP_ARGS(ifp));
    1746             : 
    1747             :         /* pass 1: check for things that need to be rejected */
    1748           0 :         p = (void*) (h+1);
    1749           0 :         for (rlen = 0; len > 1; len -= p[1], p += p[1]) {
    1750           0 :                 if (p[1] < 2 || p[1] > len) {
    1751           0 :                         free(buf, M_TEMP, 0);
    1752           0 :                         return (-1);
    1753             :                 }
    1754           0 :                 if (debug)
    1755           0 :                         addlog("%s ", sppp_lcp_opt_name(*p));
    1756           0 :                 switch (*p) {
    1757             :                 case LCP_OPT_MAGIC:
    1758             :                         /* Magic number. */
    1759             :                         /* FALLTHROUGH, both are same length */
    1760             :                 case LCP_OPT_ASYNC_MAP:
    1761             :                         /* Async control character map. */
    1762           0 :                         if (len >= 6 && p[1] == 6)
    1763             :                                 continue;
    1764           0 :                         if (debug)
    1765           0 :                                 addlog("[invalid] ");
    1766             :                         break;
    1767             :                 case LCP_OPT_MRU:
    1768             :                         /* Maximum receive unit. */
    1769           0 :                         if (len >= 4 && p[1] == 4)
    1770             :                                 continue;
    1771           0 :                         if (debug)
    1772           0 :                                 addlog("[invalid] ");
    1773             :                         break;
    1774             :                 case LCP_OPT_AUTH_PROTO:
    1775           0 :                         if (len < 4) {
    1776           0 :                                 if (debug)
    1777           0 :                                         addlog("[invalid] ");
    1778             :                                 break;
    1779             :                         }
    1780           0 :                         authproto = (p[2] << 8) + p[3];
    1781           0 :                         if (authproto == PPP_CHAP && p[1] != 5) {
    1782           0 :                                 if (debug)
    1783           0 :                                         addlog("[invalid chap len] ");
    1784             :                                 break;
    1785             :                         }
    1786           0 :                         if (sp->myauth.proto == 0) {
    1787             :                                 /* we are not configured to do auth */
    1788           0 :                                 if (debug)
    1789           0 :                                         addlog("[not configured] ");
    1790             :                                 break;
    1791             :                         }
    1792             :                         /*
    1793             :                          * Remote want us to authenticate, remember this,
    1794             :                          * so we stay in PHASE_AUTHENTICATE after LCP got
    1795             :                          * up.
    1796             :                          */
    1797           0 :                         sp->pp_flags |= PP_NEEDAUTH;
    1798           0 :                         continue;
    1799             :                 default:
    1800             :                         /* Others not supported. */
    1801           0 :                         if (debug)
    1802           0 :                                 addlog("[rej] ");
    1803             :                         break;
    1804             :                 }
    1805             :                 /* Add the option to rejected list. */
    1806           0 :                 bcopy (p, r, p[1]);
    1807           0 :                 r += p[1];
    1808           0 :                 rlen += p[1];
    1809           0 :         }
    1810           0 :         if (rlen) {
    1811           0 :                 if (debug)
    1812           0 :                         addlog(" send conf-rej\n");
    1813           0 :                 sppp_cp_send(sp, PPP_LCP, CONF_REJ, h->ident, rlen, buf);
    1814           0 :                 goto end;
    1815           0 :         } else if (debug)
    1816           0 :                 addlog("\n");
    1817             : 
    1818             :         /*
    1819             :          * pass 2: check for option values that are unacceptable and
    1820             :          * thus require to be nak'ed.
    1821             :          */
    1822           0 :         if (debug)
    1823           0 :                 log(LOG_DEBUG, SPP_FMT "lcp parse opt values: ",
    1824           0 :                     SPP_ARGS(ifp));
    1825             : 
    1826             :         p = (void*) (h+1);
    1827             :         len = origlen;
    1828           0 :         for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {
    1829           0 :                 if (debug)
    1830           0 :                         addlog("%s ", sppp_lcp_opt_name(*p));
    1831           0 :                 switch (*p) {
    1832             :                 case LCP_OPT_MAGIC:
    1833             :                         /* Magic number -- extract. */
    1834           0 :                         nmagic = (u_long)p[2] << 24 |
    1835           0 :                                 (u_long)p[3] << 16 | p[4] << 8 | p[5];
    1836           0 :                         if (nmagic != sp->lcp.magic) {
    1837           0 :                                 if (debug)
    1838           0 :                                         addlog("0x%lx ", nmagic);
    1839             :                                 continue;
    1840             :                         }
    1841           0 :                         if (debug)
    1842           0 :                                 addlog("[glitch] ");
    1843           0 :                         ++sp->pp_loopcnt;
    1844             :                         /*
    1845             :                          * We negate our magic here, and NAK it.  If
    1846             :                          * we see it later in an NAK packet, we
    1847             :                          * suggest a new one.
    1848             :                          */
    1849           0 :                         nmagic = ~sp->lcp.magic;
    1850             :                         /* Gonna NAK it. */
    1851           0 :                         p[2] = nmagic >> 24;
    1852           0 :                         p[3] = nmagic >> 16;
    1853           0 :                         p[4] = nmagic >> 8;
    1854           0 :                         p[5] = nmagic;
    1855           0 :                         break;
    1856             : 
    1857             :                 case LCP_OPT_ASYNC_MAP:
    1858             :                         /* Async control character map -- check to be zero. */
    1859           0 :                         if (! p[2] && ! p[3] && ! p[4] && ! p[5]) {
    1860           0 :                                 if (debug)
    1861           0 :                                         addlog("[empty] ");
    1862             :                                 continue;
    1863             :                         }
    1864           0 :                         if (debug)
    1865           0 :                                 addlog("[non-empty] ");
    1866             :                         /* suggest a zero one */
    1867           0 :                         p[2] = p[3] = p[4] = p[5] = 0;
    1868           0 :                         break;
    1869             : 
    1870             :                 case LCP_OPT_MRU:
    1871             :                         /*
    1872             :                          * Maximum receive unit.  Always agreeable,
    1873             :                          * but ignored by now.
    1874             :                          */
    1875           0 :                         sp->lcp.their_mru = p[2] * 256 + p[3];
    1876           0 :                         if (debug)
    1877           0 :                                 addlog("%lu ", sp->lcp.their_mru);
    1878             :                         continue;
    1879             : 
    1880             :                 case LCP_OPT_AUTH_PROTO:
    1881           0 :                         authproto = (p[2] << 8) + p[3];
    1882           0 :                         if (sp->myauth.proto != authproto) {
    1883             :                                 /* not agreed, nak */
    1884           0 :                                 if (debug)
    1885           0 :                                         addlog("[mine %s != his %s] ",
    1886           0 :                                                sppp_proto_name(sp->hisauth.proto),
    1887           0 :                                                sppp_proto_name(authproto));
    1888           0 :                                 p[2] = sp->myauth.proto >> 8;
    1889           0 :                                 p[3] = sp->myauth.proto;
    1890           0 :                                 break;
    1891             :                         }
    1892           0 :                         if (authproto == PPP_CHAP && p[4] != CHAP_MD5) {
    1893           0 :                                 if (debug)
    1894           0 :                                         addlog("[chap not MD5] ");
    1895           0 :                                 p[4] = CHAP_MD5;
    1896           0 :                                 break;
    1897             :                         }
    1898             :                         continue;
    1899             :                 }
    1900             :                 /* Add the option to nak'ed list. */
    1901           0 :                 bcopy (p, r, p[1]);
    1902           0 :                 r += p[1];
    1903           0 :                 rlen += p[1];
    1904           0 :         }
    1905           0 :         if (rlen) {
    1906           0 :                 if (++sp->fail_counter[IDX_LCP] >= sp->lcp.max_failure) {
    1907           0 :                         if (debug)
    1908           0 :                                 addlog(" max_failure (%d) exceeded, "
    1909             :                                        "send conf-rej\n",
    1910             :                                        sp->lcp.max_failure);
    1911           0 :                         sppp_cp_send(sp, PPP_LCP, CONF_REJ, h->ident, rlen, buf);
    1912           0 :                 } else {
    1913           0 :                         if (debug)
    1914           0 :                                 addlog(" send conf-nak\n");
    1915           0 :                         sppp_cp_send(sp, PPP_LCP, CONF_NAK, h->ident, rlen, buf);
    1916             :                 }
    1917             :                 goto end;
    1918             :         } else {
    1919           0 :                 if (debug)
    1920           0 :                         addlog("send conf-ack\n");
    1921           0 :                 sp->fail_counter[IDX_LCP] = 0;
    1922           0 :                 sp->pp_loopcnt = 0;
    1923           0 :                 sppp_cp_send (sp, PPP_LCP, CONF_ACK,
    1924           0 :                               h->ident, origlen, h+1);
    1925             :         }
    1926             : 
    1927             :  end:
    1928           0 :         free(buf, M_TEMP, 0);
    1929           0 :         return (rlen == 0);
    1930           0 : }
    1931             : 
    1932             : /*
    1933             :  * Analyze the LCP Configure-Reject option list, and adjust our
    1934             :  * negotiation.
    1935             :  */
    1936             : void
    1937           0 : sppp_lcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len)
    1938             : {
    1939           0 :         STDDCL;
    1940             :         u_char *p;
    1941             : 
    1942           0 :         len -= 4;
    1943             : 
    1944           0 :         if (debug)
    1945           0 :                 log(LOG_DEBUG, SPP_FMT "lcp rej opts: ",
    1946           0 :                     SPP_ARGS(ifp));
    1947             : 
    1948           0 :         p = (void*) (h+1);
    1949           0 :         for (; len > 1; len -= p[1], p += p[1]) {
    1950           0 :                 if (p[1] < 2 || p[1] > len)
    1951           0 :                         return;
    1952           0 :                 if (debug)
    1953           0 :                         addlog("%s ", sppp_lcp_opt_name(*p));
    1954           0 :                 switch (*p) {
    1955             :                 case LCP_OPT_MAGIC:
    1956             :                         /* Magic number -- can't use it, use 0 */
    1957           0 :                         sp->lcp.opts &= ~(1 << LCP_OPT_MAGIC);
    1958           0 :                         sp->lcp.magic = 0;
    1959           0 :                         break;
    1960             :                 case LCP_OPT_MRU:
    1961             :                         /*
    1962             :                          * Should not be rejected anyway, since we only
    1963             :                          * negotiate a MRU if explicitly requested by
    1964             :                          * peer.
    1965             :                          */
    1966           0 :                         sp->lcp.opts &= ~(1 << LCP_OPT_MRU);
    1967           0 :                         break;
    1968             :                 case LCP_OPT_AUTH_PROTO:
    1969             :                         /*
    1970             :                          * Peer doesn't want to authenticate himself,
    1971             :                          * deny unless this is a dialout call, and
    1972             :                          * AUTHFLAG_NOCALLOUT is set.
    1973             :                          */
    1974           0 :                         if ((sp->pp_flags & PP_CALLIN) == 0 &&
    1975           0 :                             (sp->hisauth.flags & AUTHFLAG_NOCALLOUT) != 0) {
    1976           0 :                                 if (debug)
    1977           0 :                                         addlog("[don't insist on auth "
    1978             :                                                "for callout]");
    1979           0 :                                 sp->lcp.opts &= ~(1 << LCP_OPT_AUTH_PROTO);
    1980           0 :                                 break;
    1981             :                         }
    1982           0 :                         if (debug)
    1983           0 :                                 addlog("[access denied]\n");
    1984           0 :                         lcp.Close(sp);
    1985           0 :                         break;
    1986             :                 }
    1987             :         }
    1988           0 :         if (debug)
    1989           0 :                 addlog("\n");
    1990           0 : }
    1991             : 
    1992             : /*
    1993             :  * Analyze the LCP Configure-NAK option list, and adjust our
    1994             :  * negotiation.
    1995             :  */
    1996             : void
    1997           0 : sppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len)
    1998             : {
    1999           0 :         STDDCL;
    2000             :         u_char *p;
    2001             :         u_long magic;
    2002             : 
    2003           0 :         len -= 4;
    2004             : 
    2005           0 :         if (debug)
    2006           0 :                 log(LOG_DEBUG, SPP_FMT "lcp nak opts: ",
    2007           0 :                     SPP_ARGS(ifp));
    2008             : 
    2009           0 :         p = (void*) (h+1);
    2010           0 :         for (; len > 1; len -= p[1], p += p[1]) {
    2011           0 :                 if (p[1] < 2 || p[1] > len)
    2012           0 :                         return;
    2013           0 :                 if (debug)
    2014           0 :                         addlog("%s ", sppp_lcp_opt_name(*p));
    2015           0 :                 switch (*p) {
    2016             :                 case LCP_OPT_MAGIC:
    2017             :                         /* Magic number -- renegotiate */
    2018           0 :                         if ((sp->lcp.opts & (1 << LCP_OPT_MAGIC)) &&
    2019           0 :                             len >= 6 && p[1] == 6) {
    2020           0 :                                 magic = (u_long)p[2] << 24 |
    2021           0 :                                         (u_long)p[3] << 16 | p[4] << 8 | p[5];
    2022             :                                 /*
    2023             :                                  * If the remote magic is our negated one,
    2024             :                                  * this looks like a loopback problem.
    2025             :                                  * Suggest a new magic to make sure.
    2026             :                                  */
    2027           0 :                                 if (magic == ~sp->lcp.magic) {
    2028           0 :                                         if (debug)
    2029           0 :                                                 addlog("magic glitch ");
    2030           0 :                                         sp->lcp.magic = arc4random();
    2031           0 :                                 } else {
    2032           0 :                                         sp->lcp.magic = magic;
    2033           0 :                                         if (debug)
    2034           0 :                                                 addlog("%lu ", magic);
    2035             :                                 }
    2036             :                         }
    2037             :                         break;
    2038             :                 case LCP_OPT_MRU:
    2039             :                         /*
    2040             :                          * Peer wants to advise us to negotiate an MRU.
    2041             :                          * Agree on it if it's reasonable, or use
    2042             :                          * default otherwise.
    2043             :                          */
    2044           0 :                         if (len >= 4 && p[1] == 4) {
    2045           0 :                                 u_int mru = p[2] * 256 + p[3];
    2046           0 :                                 if (debug)
    2047           0 :                                         addlog("%d ", mru);
    2048           0 :                                 if (mru < PP_MIN_MRU)
    2049           0 :                                         mru = PP_MIN_MRU;
    2050           0 :                                 if (mru > PP_MAX_MRU)
    2051           0 :                                         mru = PP_MAX_MRU;
    2052           0 :                                 sp->lcp.mru = mru;
    2053           0 :                                 sp->lcp.opts |= (1 << LCP_OPT_MRU);
    2054           0 :                         }
    2055             :                         break;
    2056             :                 case LCP_OPT_AUTH_PROTO:
    2057             :                         /*
    2058             :                          * Peer doesn't like our authentication method,
    2059             :                          * deny.
    2060             :                          */
    2061           0 :                         if (debug)
    2062           0 :                                 addlog("[access denied]\n");
    2063           0 :                         lcp.Close(sp);
    2064           0 :                         break;
    2065             :                 }
    2066             :         }
    2067           0 :         if (debug)
    2068           0 :                 addlog("\n");
    2069           0 : }
    2070             : 
    2071             : void
    2072           0 : sppp_lcp_tlu(struct sppp *sp)
    2073             : {
    2074           0 :         struct ifnet *ifp = &sp->pp_if;
    2075             :         int i;
    2076             :         u_long mask;
    2077             : 
    2078             :         /* XXX ? */
    2079           0 :         if (! (ifp->if_flags & IFF_UP) &&
    2080           0 :             (ifp->if_flags & IFF_RUNNING)) {
    2081             :                 /* Coming out of loopback mode. */
    2082           0 :                 if_up(ifp);
    2083           0 :                 if (ifp->if_flags & IFF_DEBUG)
    2084           0 :                         log(LOG_INFO, SPP_FMT "up\n", SPP_ARGS(ifp));
    2085             :         }
    2086             : 
    2087           0 :         for (i = 0; i < IDX_COUNT; i++)
    2088           0 :                 if ((cps[i])->flags & CP_QUAL)
    2089           0 :                         (cps[i])->Open(sp);
    2090             : 
    2091           0 :         if ((sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) != 0 ||
    2092           0 :             (sp->pp_flags & PP_NEEDAUTH) != 0)
    2093           0 :                 sp->pp_phase = PHASE_AUTHENTICATE;
    2094             :         else
    2095           0 :                 sp->pp_phase = PHASE_NETWORK;
    2096             : 
    2097           0 :         sppp_set_phase(sp);
    2098             : 
    2099             :         /*
    2100             :          * Open all authentication protocols.  This is even required
    2101             :          * if we already proceeded to network phase, since it might be
    2102             :          * that remote wants us to authenticate, so we might have to
    2103             :          * send a PAP request.  Undesired authentication protocols
    2104             :          * don't do anything when they get an Open event.
    2105             :          */
    2106           0 :         for (i = 0; i < IDX_COUNT; i++)
    2107           0 :                 if ((cps[i])->flags & CP_AUTH)
    2108           0 :                         (cps[i])->Open(sp);
    2109             : 
    2110           0 :         if (sp->pp_phase == PHASE_NETWORK) {
    2111             :                 /* Notify all NCPs. */
    2112           0 :                 for (i = 0; i < IDX_COUNT; i++)
    2113           0 :                         if ((cps[i])->flags & CP_NCP)
    2114           0 :                                 (cps[i])->Open(sp);
    2115             :         }
    2116             : 
    2117             :         /* Send Up events to all started protos. */
    2118           0 :         for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1)
    2119           0 :                 if (sp->lcp.protos & mask && ((cps[i])->flags & CP_LCP) == 0)
    2120           0 :                         (cps[i])->Up(sp);
    2121             : 
    2122             :         /* notify low-level driver of state change */
    2123           0 :         if (sp->pp_chg)
    2124           0 :                 sp->pp_chg(sp, (int)sp->pp_phase);
    2125             : 
    2126           0 :         if (sp->pp_phase == PHASE_NETWORK)
    2127             :                 /* if no NCP is starting, close down */
    2128           0 :                 sppp_lcp_check_and_close(sp);
    2129           0 : }
    2130             : 
    2131             : void
    2132           0 : sppp_lcp_tld(struct sppp *sp)
    2133             : {
    2134             :         int i;
    2135             :         u_long mask;
    2136             : 
    2137           0 :         sp->pp_phase = PHASE_TERMINATE;
    2138             : 
    2139           0 :         sppp_set_phase(sp);
    2140             : 
    2141             :         /*
    2142             :          * Take upper layers down.  We send the Down event first and
    2143             :          * the Close second to prevent the upper layers from sending
    2144             :          * ``a flurry of terminate-request packets'', as the RFC
    2145             :          * describes it.
    2146             :          */
    2147           0 :         for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1)
    2148           0 :                 if (sp->lcp.protos & mask && ((cps[i])->flags & CP_LCP) == 0) {
    2149           0 :                         (cps[i])->Down(sp);
    2150           0 :                         (cps[i])->Close(sp);
    2151           0 :                 }
    2152           0 : }
    2153             : 
    2154             : void
    2155           0 : sppp_lcp_tls(struct sppp *sp)
    2156             : {
    2157           0 :         sp->pp_phase = PHASE_ESTABLISH;
    2158             : 
    2159           0 :         sppp_set_phase(sp);
    2160             : 
    2161             :         /* Notify lower layer if desired. */
    2162           0 :         if (sp->pp_tls)
    2163           0 :                 (sp->pp_tls)(sp);
    2164           0 : }
    2165             : 
    2166             : void
    2167           0 : sppp_lcp_tlf(struct sppp *sp)
    2168             : {
    2169           0 :         sp->pp_phase = PHASE_DEAD;
    2170           0 :         sppp_set_phase(sp);
    2171             : 
    2172             :         /* Notify lower layer if desired. */
    2173           0 :         if (sp->pp_tlf)
    2174           0 :                 (sp->pp_tlf)(sp);
    2175           0 : }
    2176             : 
    2177             : void
    2178           0 : sppp_lcp_scr(struct sppp *sp)
    2179             : {
    2180           0 :         char opt[6 /* magicnum */ + 4 /* mru */ + 5 /* chap */];
    2181             :         int i = 0;
    2182             :         u_short authproto;
    2183             : 
    2184           0 :         if (sp->lcp.opts & (1 << LCP_OPT_MAGIC)) {
    2185           0 :                 if (! sp->lcp.magic)
    2186           0 :                         sp->lcp.magic = arc4random();
    2187           0 :                 opt[i++] = LCP_OPT_MAGIC;
    2188           0 :                 opt[i++] = 6;
    2189           0 :                 opt[i++] = sp->lcp.magic >> 24;
    2190           0 :                 opt[i++] = sp->lcp.magic >> 16;
    2191           0 :                 opt[i++] = sp->lcp.magic >> 8;
    2192           0 :                 opt[i++] = sp->lcp.magic;
    2193           0 :         }
    2194             : 
    2195           0 :         if (sp->lcp.opts & (1 << LCP_OPT_MRU)) {
    2196           0 :                 opt[i++] = LCP_OPT_MRU;
    2197           0 :                 opt[i++] = 4;
    2198           0 :                 opt[i++] = sp->lcp.mru >> 8;
    2199           0 :                 opt[i++] = sp->lcp.mru;
    2200           0 :         }
    2201             : 
    2202           0 :         if (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) {
    2203           0 :                 authproto = sp->hisauth.proto;
    2204           0 :                 opt[i++] = LCP_OPT_AUTH_PROTO;
    2205           0 :                 opt[i++] = authproto == PPP_CHAP? 5: 4;
    2206           0 :                 opt[i++] = authproto >> 8;
    2207           0 :                 opt[i++] = authproto;
    2208           0 :                 if (authproto == PPP_CHAP)
    2209           0 :                         opt[i++] = CHAP_MD5;
    2210             :         }
    2211             : 
    2212           0 :         sp->confid[IDX_LCP] = ++sp->pp_seq;
    2213           0 :         sppp_cp_send (sp, PPP_LCP, CONF_REQ, sp->confid[IDX_LCP], i, opt);
    2214           0 : }
    2215             : 
    2216             : /*
    2217             :  * Check the open NCPs, return true if at least one NCP is open.
    2218             :  */
    2219             : int
    2220           0 : sppp_ncp_check(struct sppp *sp)
    2221             : {
    2222             :         int i, mask;
    2223             : 
    2224           0 :         for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1)
    2225           0 :                 if (sp->lcp.protos & mask && (cps[i])->flags & CP_NCP)
    2226           0 :                         return 1;
    2227           0 :         return 0;
    2228           0 : }
    2229             : 
    2230             : /*
    2231             :  * Re-check the open NCPs and see if we should terminate the link.
    2232             :  * Called by the NCPs during their tlf action handling.
    2233             :  */
    2234             : void
    2235           0 : sppp_lcp_check_and_close(struct sppp *sp)
    2236             : {
    2237             : 
    2238           0 :         if (sp->pp_phase < PHASE_NETWORK)
    2239             :                 /* don't bother, we are already going down */
    2240             :                 return;
    2241             : 
    2242           0 :         if (sppp_ncp_check(sp))
    2243             :                 return;
    2244             : 
    2245           0 :         lcp.Close(sp);
    2246           0 : }
    2247             : /*
    2248             :  *--------------------------------------------------------------------------*
    2249             :  *                                                                          *
    2250             :  *                        The IPCP implementation.                          *
    2251             :  *                                                                          *
    2252             :  *--------------------------------------------------------------------------*
    2253             :  */
    2254             : 
    2255             : void
    2256           0 : sppp_ipcp_init(struct sppp *sp)
    2257             : {
    2258           0 :         sp->ipcp.opts = 0;
    2259           0 :         sp->ipcp.flags = 0;
    2260           0 :         sp->state[IDX_IPCP] = STATE_INITIAL;
    2261           0 :         sp->fail_counter[IDX_IPCP] = 0;
    2262           0 :         task_set(&sp->ipcp.set_addr_task, sppp_set_ip_addrs, sp);
    2263           0 :         task_set(&sp->ipcp.clear_addr_task, sppp_clear_ip_addrs, sp);
    2264           0 : }
    2265             : 
    2266             : void
    2267           0 : sppp_ipcp_destroy(struct sppp *sp)
    2268             : {
    2269           0 :         task_del(systq, &sp->ipcp.set_addr_task);
    2270           0 :         task_del(systq, &sp->ipcp.clear_addr_task);
    2271           0 : }
    2272             : 
    2273             : void
    2274           0 : sppp_ipcp_up(struct sppp *sp)
    2275             : {
    2276           0 :         sppp_up_event(&ipcp, sp);
    2277           0 : }
    2278             : 
    2279             : void
    2280           0 : sppp_ipcp_down(struct sppp *sp)
    2281             : {
    2282           0 :         sppp_down_event(&ipcp, sp);
    2283           0 : }
    2284             : 
    2285             : void
    2286           0 : sppp_ipcp_open(struct sppp *sp)
    2287             : {
    2288           0 :         sppp_open_event(&ipcp, sp);
    2289           0 : }
    2290             : 
    2291             : void
    2292           0 : sppp_ipcp_close(struct sppp *sp)
    2293             : {
    2294           0 :         sppp_close_event(&ipcp, sp);
    2295           0 : }
    2296             : 
    2297             : void
    2298           0 : sppp_ipcp_TO(void *cookie)
    2299             : {
    2300           0 :         sppp_to_event(&ipcp, (struct sppp *)cookie);
    2301           0 : }
    2302             : 
    2303             : /*
    2304             :  * Analyze a configure request.  Return true if it was agreeable, and
    2305             :  * caused action sca, false if it has been rejected or nak'ed, and
    2306             :  * caused action scn.  (The return value is used to make the state
    2307             :  * transition decision in the state automaton.)
    2308             :  */
    2309             : int
    2310           0 : sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len)
    2311             : {
    2312             :         u_char *buf, *r, *p;
    2313           0 :         struct ifnet *ifp = &sp->pp_if;
    2314           0 :         int rlen, origlen, debug = ifp->if_flags & IFF_DEBUG;
    2315           0 :         u_int32_t hisaddr, desiredaddr;
    2316             : 
    2317           0 :         len -= 4;
    2318             :         origlen = len;
    2319             :         /*
    2320             :          * Make sure to allocate a buf that can at least hold a
    2321             :          * conf-nak with an `address' option.  We might need it below.
    2322             :          */
    2323           0 :         buf = r = malloc ((len < 6? 6: len), M_TEMP, M_NOWAIT);
    2324           0 :         if (! buf)
    2325           0 :                 return (0);
    2326             : 
    2327             :         /* pass 1: see if we can recognize them */
    2328           0 :         if (debug)
    2329           0 :                 log(LOG_DEBUG, SPP_FMT "ipcp parse opts: ",
    2330           0 :                     SPP_ARGS(ifp));
    2331           0 :         p = (void*) (h+1);
    2332           0 :         for (rlen = 0; len > 1; len -= p[1], p += p[1]) {
    2333           0 :                 if (p[1] < 2 || p[1] > len) {
    2334           0 :                         free(buf, M_TEMP, 0);
    2335           0 :                         return (-1);
    2336             :                 }
    2337           0 :                 if (debug)
    2338           0 :                         addlog("%s ", sppp_ipcp_opt_name(*p));
    2339           0 :                 switch (*p) {
    2340             : #ifdef notyet
    2341             :                 case IPCP_OPT_COMPRESSION:
    2342             :                         if (len >= 6 && p[1] >= 6) {
    2343             :                                 /* correctly formed compress option */
    2344             :                                 continue;
    2345             :                         }
    2346             :                         if (debug)
    2347             :                                 addlog("[invalid] ");
    2348             :                         break;
    2349             : #endif
    2350             :                 case IPCP_OPT_ADDRESS:
    2351           0 :                         if (len >= 6 && p[1] == 6) {
    2352             :                                 /* correctly formed address option */
    2353             :                                 continue;
    2354             :                         }
    2355           0 :                         if (debug)
    2356           0 :                                 addlog("[invalid] ");
    2357             :                         break;
    2358             :                 default:
    2359             :                         /* Others not supported. */
    2360           0 :                         if (debug)
    2361           0 :                                 addlog("[rej] ");
    2362             :                         break;
    2363             :                 }
    2364             :                 /* Add the option to rejected list. */
    2365           0 :                 bcopy (p, r, p[1]);
    2366           0 :                 r += p[1];
    2367           0 :                 rlen += p[1];
    2368           0 :         }
    2369           0 :         if (rlen) {
    2370           0 :                 if (debug)
    2371           0 :                         addlog(" send conf-rej\n");
    2372           0 :                 sppp_cp_send(sp, PPP_IPCP, CONF_REJ, h->ident, rlen, buf);
    2373           0 :                 goto end;
    2374           0 :         } else if (debug)
    2375           0 :                 addlog("\n");
    2376             : 
    2377             :         /* pass 2: parse option values */
    2378           0 :         if (sp->ipcp.flags & IPCP_HISADDR_SEEN)
    2379           0 :                 hisaddr = sp->ipcp.req_hisaddr; /* we already agreed on that */
    2380             :         else
    2381           0 :                 sppp_get_ip_addrs(sp, 0, &hisaddr, 0); /* user configuration */
    2382           0 :         if (debug)
    2383           0 :                 log(LOG_DEBUG, SPP_FMT "ipcp parse opt values: ",
    2384           0 :                        SPP_ARGS(ifp));
    2385             :         p = (void*) (h+1);
    2386             :         len = origlen;
    2387           0 :         for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {
    2388           0 :                 if (debug)
    2389           0 :                         addlog(" %s ", sppp_ipcp_opt_name(*p));
    2390           0 :                 switch (*p) {
    2391             : #ifdef notyet
    2392             :                 case IPCP_OPT_COMPRESSION:
    2393             :                         continue;
    2394             : #endif
    2395             :                 case IPCP_OPT_ADDRESS:
    2396           0 :                         desiredaddr = p[2] << 24 | p[3] << 16 |
    2397           0 :                                 p[4] << 8 | p[5];
    2398           0 :                         if (desiredaddr == hisaddr ||
    2399           0 :                             ((sp->ipcp.flags & IPCP_HISADDR_DYN) &&
    2400           0 :                             desiredaddr != 0)) {
    2401             :                                 /*
    2402             :                                  * Peer's address is same as our value,
    2403             :                                  * or we have set it to 0.0.0.1 to
    2404             :                                  * indicate that we do not really care,
    2405             :                                  * this is agreeable.  Gonna conf-ack
    2406             :                                  * it.
    2407             :                                  */
    2408           0 :                                 if (debug)
    2409           0 :                                         addlog("%s [ack] ",
    2410           0 :                                                sppp_dotted_quad(desiredaddr));
    2411             :                                 /* record that we've seen it already */
    2412           0 :                                 sp->ipcp.flags |= IPCP_HISADDR_SEEN;
    2413           0 :                                 sp->ipcp.req_hisaddr = desiredaddr;
    2414           0 :                                 hisaddr = desiredaddr;
    2415           0 :                                 continue;
    2416             :                         }
    2417             :                         /*
    2418             :                          * The address wasn't agreeable.  This is either
    2419             :                          * he sent us 0.0.0.0, asking to assign him an
    2420             :                          * address, or he send us another address not
    2421             :                          * matching our value.  Either case, we gonna
    2422             :                          * conf-nak it with our value.
    2423             :                          */
    2424           0 :                         if (debug) {
    2425           0 :                                 if (desiredaddr == 0)
    2426           0 :                                         addlog("[addr requested] ");
    2427             :                                 else
    2428           0 :                                         addlog("%s [not agreed] ",
    2429           0 :                                                sppp_dotted_quad(desiredaddr));
    2430             :                         }
    2431             : 
    2432           0 :                         p[2] = hisaddr >> 24;
    2433           0 :                         p[3] = hisaddr >> 16;
    2434           0 :                         p[4] = hisaddr >> 8;
    2435           0 :                         p[5] = hisaddr;
    2436           0 :                         break;
    2437             :                 }
    2438             :                 /* Add the option to nak'ed list. */
    2439           0 :                 bcopy (p, r, p[1]);
    2440           0 :                 r += p[1];
    2441           0 :                 rlen += p[1];
    2442           0 :         }
    2443             : 
    2444             :         /*
    2445             :          * If we are about to conf-ack the request, but haven't seen
    2446             :          * his address so far, gonna conf-nak it instead, with the
    2447             :          * `address' option present and our idea of his address being
    2448             :          * filled in there, to request negotiation of both addresses.
    2449             :          *
    2450             :          * XXX This can result in an endless req - nak loop if peer
    2451             :          * doesn't want to send us his address.  Q: What should we do
    2452             :          * about it?  XXX  A: implement the max-failure counter.
    2453             :          */
    2454           0 :         if (rlen == 0 && !(sp->ipcp.flags & IPCP_HISADDR_SEEN)) {
    2455           0 :                 buf[0] = IPCP_OPT_ADDRESS;
    2456           0 :                 buf[1] = 6;
    2457           0 :                 buf[2] = hisaddr >> 24;
    2458           0 :                 buf[3] = hisaddr >> 16;
    2459           0 :                 buf[4] = hisaddr >> 8;
    2460           0 :                 buf[5] = hisaddr;
    2461             :                 rlen = 6;
    2462           0 :                 if (debug)
    2463           0 :                         addlog("still need hisaddr ");
    2464             :         }
    2465             : 
    2466           0 :         if (rlen) {
    2467           0 :                 if (debug)
    2468           0 :                         addlog(" send conf-nak\n");
    2469           0 :                 sppp_cp_send (sp, PPP_IPCP, CONF_NAK, h->ident, rlen, buf);
    2470           0 :         } else {
    2471           0 :                 if (debug)
    2472           0 :                         addlog(" send conf-ack\n");
    2473           0 :                 sppp_cp_send (sp, PPP_IPCP, CONF_ACK,
    2474           0 :                               h->ident, origlen, h+1);
    2475             :         }
    2476             : 
    2477             :  end:
    2478           0 :         free(buf, M_TEMP, 0);
    2479           0 :         return (rlen == 0);
    2480           0 : }
    2481             : 
    2482             : /*
    2483             :  * Analyze the IPCP Configure-Reject option list, and adjust our
    2484             :  * negotiation.
    2485             :  */
    2486             : void
    2487           0 : sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len)
    2488             : {
    2489             :         u_char *p;
    2490           0 :         struct ifnet *ifp = &sp->pp_if;
    2491           0 :         int debug = ifp->if_flags & IFF_DEBUG;
    2492             : 
    2493           0 :         len -= 4;
    2494             : 
    2495           0 :         if (debug)
    2496           0 :                 log(LOG_DEBUG, SPP_FMT "ipcp rej opts: ",
    2497           0 :                     SPP_ARGS(ifp));
    2498             : 
    2499           0 :         p = (void*) (h+1);
    2500           0 :         for (; len > 1; len -= p[1], p += p[1]) {
    2501           0 :                 if (p[1] < 2 || p[1] > len)
    2502           0 :                         return;
    2503           0 :                 if (debug)
    2504           0 :                         addlog("%s ", sppp_ipcp_opt_name(*p));
    2505           0 :                 switch (*p) {
    2506             :                 case IPCP_OPT_ADDRESS:
    2507             :                         /*
    2508             :                          * Peer doesn't grok address option.  This is
    2509             :                          * bad.  XXX  Should we better give up here?
    2510             :                          */
    2511           0 :                         sp->ipcp.opts &= ~(1 << IPCP_OPT_ADDRESS);
    2512           0 :                         break;
    2513             : #ifdef notyet
    2514             :                 case IPCP_OPT_COMPRESS:
    2515             :                         sp->ipcp.opts &= ~(1 << IPCP_OPT_COMPRESS);
    2516             :                         break;
    2517             : #endif
    2518             :                 }
    2519             :         }
    2520           0 :         if (debug)
    2521           0 :                 addlog("\n");
    2522           0 : }
    2523             : 
    2524             : /*
    2525             :  * Analyze the IPCP Configure-NAK option list, and adjust our
    2526             :  * negotiation.
    2527             :  */
    2528             : void
    2529           0 : sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len)
    2530             : {
    2531             :         u_char *p;
    2532           0 :         struct ifnet *ifp = &sp->pp_if;
    2533           0 :         int debug = ifp->if_flags & IFF_DEBUG;
    2534             :         u_int32_t wantaddr;
    2535             : 
    2536           0 :         len -= 4;
    2537             : 
    2538           0 :         if (debug)
    2539           0 :                 log(LOG_DEBUG, SPP_FMT "ipcp nak opts: ",
    2540           0 :                     SPP_ARGS(ifp));
    2541             : 
    2542           0 :         p = (void*) (h+1);
    2543           0 :         for (; len > 1; len -= p[1], p += p[1]) {
    2544           0 :                 if (p[1] < 2 || p[1] > len)
    2545           0 :                         return;
    2546           0 :                 if (debug)
    2547           0 :                         addlog("%s ", sppp_ipcp_opt_name(*p));
    2548           0 :                 switch (*p) {
    2549             :                 case IPCP_OPT_ADDRESS:
    2550             :                         /*
    2551             :                          * Peer doesn't like our local IP address.  See
    2552             :                          * if we can do something for him.  We'll drop
    2553             :                          * him our address then.
    2554             :                          */
    2555           0 :                         if (len >= 6 && p[1] == 6) {
    2556           0 :                                 wantaddr = p[2] << 24 | p[3] << 16 |
    2557           0 :                                         p[4] << 8 | p[5];
    2558           0 :                                 sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS);
    2559           0 :                                 if (debug)
    2560           0 :                                         addlog("[wantaddr %s] ",
    2561           0 :                                                sppp_dotted_quad(wantaddr));
    2562             :                                 /*
    2563             :                                  * When doing dynamic address assignment,
    2564             :                                  * we accept his offer.  Otherwise, we
    2565             :                                  * ignore it and thus continue to negotiate
    2566             :                                  * our already existing value.
    2567             :                                  */
    2568           0 :                                 if (sp->ipcp.flags & IPCP_MYADDR_DYN) {
    2569           0 :                                         if (debug)
    2570           0 :                                                 addlog("[agree] ");
    2571           0 :                                         sp->ipcp.flags |= IPCP_MYADDR_SEEN;
    2572           0 :                                         sp->ipcp.req_myaddr = wantaddr;
    2573           0 :                                 }
    2574             :                         }
    2575             :                         break;
    2576             : #ifdef notyet
    2577             :                 case IPCP_OPT_COMPRESS:
    2578             :                         /*
    2579             :                          * Peer wants different compression parameters.
    2580             :                          */
    2581             :                         break;
    2582             : #endif
    2583             :                 }
    2584             :         }
    2585           0 :         if (debug)
    2586           0 :                 addlog("\n");
    2587           0 : }
    2588             : 
    2589             : void
    2590           0 : sppp_ipcp_tlu(struct sppp *sp)
    2591             : {
    2592           0 :         if (sp->ipcp.req_myaddr != 0 || sp->ipcp.req_hisaddr != 0)
    2593           0 :                 task_add(systq, &sp->ipcp.set_addr_task);
    2594           0 : }
    2595             : 
    2596             : void
    2597           0 : sppp_ipcp_tld(struct sppp *sp)
    2598             : {
    2599           0 : }
    2600             : 
    2601             : void
    2602           0 : sppp_ipcp_tls(struct sppp *sp)
    2603             : {
    2604           0 :         STDDCL;
    2605           0 :         u_int32_t myaddr, hisaddr;
    2606             : 
    2607           0 :         sp->ipcp.flags &= ~(IPCP_HISADDR_SEEN|IPCP_MYADDR_SEEN|
    2608             :             IPCP_MYADDR_DYN|IPCP_HISADDR_DYN);
    2609           0 :         sp->ipcp.req_myaddr = 0;
    2610           0 :         sp->ipcp.req_hisaddr = 0;
    2611             : 
    2612           0 :         sppp_get_ip_addrs(sp, &myaddr, &hisaddr, 0);
    2613             :         /*
    2614             :          * If we don't have his address, this probably means our
    2615             :          * interface doesn't want to talk IP at all.  (This could
    2616             :          * be the case if somebody wants to speak only IPX, for
    2617             :          * example.)  Don't open IPCP in this case.
    2618             :          */
    2619           0 :         if (hisaddr == 0) {
    2620             :                 /* XXX this message should go away */
    2621           0 :                 if (debug)
    2622           0 :                         log(LOG_DEBUG, SPP_FMT "ipcp_open(): no IP interface\n",
    2623           0 :                             SPP_ARGS(ifp));
    2624           0 :                 return;
    2625             :         }
    2626             : 
    2627           0 :         if (myaddr == 0) {
    2628             :                 /*
    2629             :                  * I don't have an assigned address, so i need to
    2630             :                  * negotiate my address.
    2631             :                  */
    2632           0 :                 sp->ipcp.flags |= IPCP_MYADDR_DYN;
    2633           0 :                 sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS);
    2634           0 :         }
    2635           0 :         if (hisaddr >= 1 && hisaddr <= 255) {
    2636             :                 /*
    2637             :                  * XXX - remove this hack!
    2638             :                  * remote has no valid address, we need to get one assigned.
    2639             :                  */
    2640           0 :                 sp->ipcp.flags |= IPCP_HISADDR_DYN;
    2641           0 :         }
    2642             : 
    2643             :         /* indicate to LCP that it must stay alive */
    2644           0 :         sp->lcp.protos |= (1 << IDX_IPCP);
    2645           0 : }
    2646             : 
    2647             : void
    2648           0 : sppp_ipcp_tlf(struct sppp *sp)
    2649             : {
    2650           0 :         if (sp->ipcp.flags & (IPCP_MYADDR_DYN|IPCP_HISADDR_DYN))
    2651             :                 /* Some address was dynamic, clear it again. */
    2652           0 :                 task_add(systq, &sp->ipcp.clear_addr_task);
    2653             : 
    2654             :         /* we no longer need LCP */
    2655           0 :         sp->lcp.protos &= ~(1 << IDX_IPCP);
    2656           0 :         sppp_lcp_check_and_close(sp);
    2657           0 : }
    2658             : 
    2659             : void
    2660           0 : sppp_ipcp_scr(struct sppp *sp)
    2661             : {
    2662           0 :         char opt[6 /* compression */ + 6 /* address */];
    2663           0 :         u_int32_t ouraddr;
    2664             :         int i = 0;
    2665             : 
    2666             : #ifdef notyet
    2667             :         if (sp->ipcp.opts & (1 << IPCP_OPT_COMPRESSION)) {
    2668             :                 opt[i++] = IPCP_OPT_COMPRESSION;
    2669             :                 opt[i++] = 6;
    2670             :                 opt[i++] = 0;   /* VJ header compression */
    2671             :                 opt[i++] = 0x2d; /* VJ header compression */
    2672             :                 opt[i++] = max_slot_id;
    2673             :                 opt[i++] = comp_slot_id;
    2674             :         }
    2675             : #endif
    2676             : 
    2677           0 :         if (sp->ipcp.opts & (1 << IPCP_OPT_ADDRESS)) {
    2678           0 :                 if (sp->ipcp.flags & IPCP_MYADDR_SEEN)
    2679             :                         /* not sure if this can ever happen */
    2680           0 :                         ouraddr = sp->ipcp.req_myaddr;
    2681             :                 else
    2682           0 :                         sppp_get_ip_addrs(sp, &ouraddr, 0, 0);
    2683           0 :                 opt[i++] = IPCP_OPT_ADDRESS;
    2684           0 :                 opt[i++] = 6;
    2685           0 :                 opt[i++] = ouraddr >> 24;
    2686           0 :                 opt[i++] = ouraddr >> 16;
    2687           0 :                 opt[i++] = ouraddr >> 8;
    2688           0 :                 opt[i++] = ouraddr;
    2689           0 :         }
    2690             : 
    2691           0 :         sp->confid[IDX_IPCP] = ++sp->pp_seq;
    2692           0 :         sppp_cp_send(sp, PPP_IPCP, CONF_REQ, sp->confid[IDX_IPCP], i, opt);
    2693           0 : }
    2694             : 
    2695             : /*
    2696             :  *--------------------------------------------------------------------------*
    2697             :  *                                                                          *
    2698             :  *                      The IPv6CP implementation.                          *
    2699             :  *                                                                          *
    2700             :  *--------------------------------------------------------------------------*
    2701             :  */
    2702             : 
    2703             : #ifdef INET6
    2704             : void
    2705           0 : sppp_ipv6cp_init(struct sppp *sp)
    2706             : {
    2707           0 :         sp->ipv6cp.opts = 0;
    2708           0 :         sp->ipv6cp.flags = 0;
    2709           0 :         sp->state[IDX_IPV6CP] = STATE_INITIAL;
    2710           0 :         sp->fail_counter[IDX_IPV6CP] = 0;
    2711           0 :         task_set(&sp->ipv6cp.set_addr_task, sppp_update_ip6_addr, sp);
    2712           0 : }
    2713             : 
    2714             : void
    2715           0 : sppp_ipv6cp_destroy(struct sppp *sp)
    2716             : {
    2717           0 :         task_del(systq, &sp->ipv6cp.set_addr_task);
    2718           0 : }
    2719             : 
    2720             : void
    2721           0 : sppp_ipv6cp_up(struct sppp *sp)
    2722             : {
    2723           0 :         sppp_up_event(&ipv6cp, sp);
    2724           0 : }
    2725             : 
    2726             : void
    2727           0 : sppp_ipv6cp_down(struct sppp *sp)
    2728             : {
    2729           0 :         sppp_down_event(&ipv6cp, sp);
    2730           0 : }
    2731             : 
    2732             : void
    2733           0 : sppp_ipv6cp_open(struct sppp *sp)
    2734             : {
    2735           0 :         STDDCL;
    2736           0 :         struct in6_addr myaddr, hisaddr;
    2737             : 
    2738           0 :         sp->ipv6cp.flags &= ~(IPV6CP_MYIFID_SEEN|IPV6CP_MYIFID_DYN);
    2739             : 
    2740           0 :         sppp_get_ip6_addrs(sp, &myaddr, &hisaddr, NULL);
    2741             :         /*
    2742             :          * If we don't have our address, this probably means our
    2743             :          * interface doesn't want to talk IPv6 at all.  (This could
    2744             :          * be the case if the IFXF_NOINET6 flag is set, for
    2745             :          * example.)  Don't open IPv6CP in this case.
    2746             :          */
    2747           0 :         if (IN6_IS_ADDR_UNSPECIFIED(&myaddr)) {
    2748             :                 /* XXX this message should go away */
    2749           0 :                 if (debug)
    2750           0 :                         log(LOG_DEBUG, SPP_FMT "ipv6cp_open(): no IPv6 interface\n",
    2751           0 :                             SPP_ARGS(ifp));
    2752           0 :                 return;
    2753             :         }
    2754           0 :         sp->ipv6cp.opts |= (1 << IPV6CP_OPT_IFID);
    2755           0 :         sppp_open_event(&ipv6cp, sp);
    2756           0 : }
    2757             : 
    2758             : void
    2759           0 : sppp_ipv6cp_close(struct sppp *sp)
    2760             : {
    2761           0 :         sppp_close_event(&ipv6cp, sp);
    2762           0 : }
    2763             : 
    2764             : void
    2765           0 : sppp_ipv6cp_TO(void *cookie)
    2766             : {
    2767           0 :         sppp_to_event(&ipv6cp, (struct sppp *)cookie);
    2768           0 : }
    2769             : 
    2770             : int
    2771           0 : sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len)
    2772             : {
    2773             :         u_char *buf, *r, *p;
    2774           0 :         struct ifnet *ifp = &sp->pp_if;
    2775           0 :         int rlen, origlen, debug = ifp->if_flags & IFF_DEBUG;
    2776           0 :         struct in6_addr myaddr, desiredaddr, suggestaddr;
    2777             :         int ifidcount;
    2778             :         int type;
    2779             :         int collision, nohisaddr;
    2780           0 :         char addr[INET6_ADDRSTRLEN];
    2781             : 
    2782           0 :         len -= 4;
    2783             :         origlen = len;
    2784             :         /*
    2785             :          * Make sure to allocate a buf that can at least hold a
    2786             :          * conf-nak with an `address' option.  We might need it below.
    2787             :          */
    2788           0 :         buf = r = malloc ((len < 6? 6: len), M_TEMP, M_NOWAIT);
    2789           0 :         if (! buf)
    2790           0 :                 return (0);
    2791             : 
    2792             :         /* pass 1: see if we can recognize them */
    2793           0 :         if (debug)
    2794           0 :                 log(LOG_DEBUG, "%s: ipv6cp parse opts:",
    2795           0 :                     SPP_ARGS(ifp));
    2796           0 :         p = (void *)(h + 1);
    2797             :         ifidcount = 0;
    2798           0 :         for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {
    2799             :                 /* Sanity check option length */
    2800           0 :                 if (p[1] < 2 || p[1] > len) {
    2801           0 :                         free(buf, M_TEMP, 0);
    2802           0 :                         return (-1);
    2803             :                 }
    2804           0 :                 if (debug)
    2805           0 :                         addlog(" %s", sppp_ipv6cp_opt_name(*p));
    2806           0 :                 switch (*p) {
    2807             :                 case IPV6CP_OPT_IFID:
    2808           0 :                         if (len >= 10 && p[1] == 10 && ifidcount == 0) {
    2809             :                                 /* correctly formed address option */
    2810           0 :                                 ifidcount++;
    2811           0 :                                 continue;
    2812             :                         }
    2813           0 :                         if (debug)
    2814           0 :                                 addlog(" [invalid]");
    2815             :                         break;
    2816             : #ifdef notyet
    2817             :                 case IPV6CP_OPT_COMPRESSION:
    2818             :                         if (len >= 4 && p[1] >= 4) {
    2819             :                                 /* correctly formed compress option */
    2820             :                                 continue;
    2821             :                         }
    2822             :                         if (debug)
    2823             :                                 addlog(" [invalid]");
    2824             :                         break;
    2825             : #endif
    2826             :                 default:
    2827             :                         /* Others not supported. */
    2828           0 :                         if (debug)
    2829           0 :                                 addlog(" [rej]");
    2830             :                         break;
    2831             :                 }
    2832             :                 /* Add the option to rejected list. */
    2833           0 :                 bcopy (p, r, p[1]);
    2834           0 :                 r += p[1];
    2835           0 :                 rlen += p[1];
    2836           0 :         }
    2837           0 :         if (rlen) {
    2838           0 :                 if (debug)
    2839           0 :                         addlog(" send conf-rej\n");
    2840           0 :                 sppp_cp_send(sp, PPP_IPV6CP, CONF_REJ, h->ident, rlen, buf);
    2841           0 :                 goto end;
    2842           0 :         } else if (debug)
    2843           0 :                 addlog("\n");
    2844             : 
    2845             :         /* pass 2: parse option values */
    2846           0 :         if (sp->ipv6cp.flags & IPV6CP_MYIFID_DYN)
    2847           0 :                 myaddr = sp->ipv6cp.req_ifid.ifra_addr.sin6_addr;
    2848             :         else
    2849           0 :                 sppp_get_ip6_addrs(sp, &myaddr, NULL, NULL);
    2850           0 :         if (debug)
    2851           0 :                 log(LOG_DEBUG, "%s: ipv6cp parse opt values: ",
    2852           0 :                        SPP_ARGS(ifp));
    2853             :         p = (void *)(h + 1);
    2854             :         len = origlen;
    2855             :         type = CONF_ACK;
    2856           0 :         for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {
    2857           0 :                 if (debug)
    2858           0 :                         addlog(" %s", sppp_ipv6cp_opt_name(*p));
    2859           0 :                 switch (*p) {
    2860             : #ifdef notyet
    2861             :                 case IPV6CP_OPT_COMPRESSION:
    2862             :                         continue;
    2863             : #endif
    2864             :                 case IPV6CP_OPT_IFID:
    2865           0 :                         memset(&desiredaddr, 0, sizeof(desiredaddr));
    2866           0 :                         bcopy(&p[2], &desiredaddr.s6_addr[8], 8);
    2867           0 :                         collision = (memcmp(&desiredaddr.s6_addr[8],
    2868           0 :                                         &myaddr.s6_addr[8], 8) == 0);
    2869           0 :                         nohisaddr = IN6_IS_ADDR_UNSPECIFIED(&desiredaddr);
    2870             : 
    2871           0 :                         desiredaddr.s6_addr16[0] = htons(0xfe80);
    2872             : 
    2873           0 :                         if (!collision && !nohisaddr) {
    2874             :                                 /* no collision, hisaddr known - Conf-Ack */
    2875             :                                 type = CONF_ACK;
    2876             : 
    2877           0 :                                 if (debug) {
    2878           0 :                                         addlog(" %s [%s]",
    2879           0 :                                             inet_ntop(AF_INET6, &desiredaddr,
    2880           0 :                                                 addr, sizeof(addr)),
    2881           0 :                                             sppp_cp_type_name(type));
    2882           0 :                                 }
    2883           0 :                                 sppp_set_ip6_addr(sp, &myaddr, &desiredaddr);
    2884           0 :                                 continue;
    2885             :                         }
    2886             : 
    2887           0 :                         memset(&suggestaddr, 0, sizeof(suggestaddr));
    2888           0 :                         if (collision && nohisaddr) {
    2889             :                                 /* collision, hisaddr unknown - Conf-Rej */
    2890             :                                 type = CONF_REJ;
    2891           0 :                                 memset(&p[2], 0, 8);
    2892           0 :                         } else {
    2893             :                                 /*
    2894             :                                  * - no collision, hisaddr unknown, or
    2895             :                                  * - collision, hisaddr known
    2896             :                                  * Conf-Nak, suggest hisaddr
    2897             :                                  */
    2898             :                                 type = CONF_NAK;
    2899           0 :                                 sppp_suggest_ip6_addr(sp, &suggestaddr);
    2900           0 :                                 bcopy(&suggestaddr.s6_addr[8], &p[2], 8);
    2901             :                         }
    2902           0 :                         if (debug)
    2903           0 :                                 addlog(" %s [%s]",
    2904           0 :                                     inet_ntop(AF_INET6, &desiredaddr, addr,
    2905             :                                         sizeof(addr)),
    2906           0 :                                     sppp_cp_type_name(type));
    2907             :                         break;
    2908             :                 }
    2909             :                 /* Add the option to nak'ed list. */
    2910           0 :                 bcopy (p, r, p[1]);
    2911           0 :                 r += p[1];
    2912           0 :                 rlen += p[1];
    2913           0 :         }
    2914             : 
    2915           0 :         if (rlen == 0 && type == CONF_ACK) {
    2916           0 :                 if (debug)
    2917           0 :                         addlog(" send %s\n", sppp_cp_type_name(type));
    2918           0 :                 sppp_cp_send(sp, PPP_IPV6CP, type, h->ident, origlen, h + 1);
    2919           0 :         } else {
    2920             : #ifdef notdef
    2921             :                 if (type == CONF_ACK)
    2922             :                         panic("IPv6CP RCR: CONF_ACK with non-zero rlen");
    2923             : #endif
    2924             : 
    2925           0 :                 if (debug) {
    2926           0 :                         addlog(" send %s suggest %s\n",
    2927           0 :                             sppp_cp_type_name(type),
    2928           0 :                             inet_ntop(AF_INET6, &suggestaddr, addr,
    2929             :                                 sizeof(addr)));
    2930           0 :                 }
    2931           0 :                 sppp_cp_send(sp, PPP_IPV6CP, type, h->ident, rlen, buf);
    2932             :         }
    2933             : 
    2934             : end:
    2935           0 :         free(buf, M_TEMP, 0);
    2936           0 :         return (rlen == 0);
    2937           0 : }
    2938             : 
    2939             : void
    2940           0 : sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len)
    2941             : {
    2942             :         u_char *p;
    2943           0 :         struct ifnet *ifp = &sp->pp_if;
    2944           0 :         int debug = ifp->if_flags & IFF_DEBUG;
    2945             : 
    2946           0 :         len -= 4;
    2947             : 
    2948           0 :         if (debug)
    2949           0 :                 log(LOG_DEBUG, "%s: ipv6cp rej opts:",
    2950           0 :                     SPP_ARGS(ifp));
    2951             : 
    2952           0 :         p = (void *)(h + 1);
    2953           0 :         for (; len > 1 && p[1]; len -= p[1], p += p[1]) {
    2954           0 :                 if (p[1] < 2 || p[1] > len)
    2955           0 :                         return;
    2956           0 :                 if (debug)
    2957           0 :                         addlog(" %s", sppp_ipv6cp_opt_name(*p));
    2958           0 :                 switch (*p) {
    2959             :                 case IPV6CP_OPT_IFID:
    2960             :                         /*
    2961             :                          * Peer doesn't grok address option.  This is
    2962             :                          * bad.  XXX  Should we better give up here?
    2963             :                          */
    2964           0 :                         sp->ipv6cp.opts &= ~(1 << IPV6CP_OPT_IFID);
    2965           0 :                         break;
    2966             : #ifdef notyet
    2967             :                 case IPV6CP_OPT_COMPRESS:
    2968             :                         sp->ipv6cp.opts &= ~(1 << IPV6CP_OPT_COMPRESS);
    2969             :                         break;
    2970             : #endif
    2971             :                 }
    2972             :         }
    2973           0 :         if (debug)
    2974           0 :                 addlog("\n");
    2975           0 :         return;
    2976           0 : }
    2977             : 
    2978             : void
    2979           0 : sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len)
    2980             : {
    2981             :         u_char *p;
    2982           0 :         struct ifnet *ifp = &sp->pp_if;
    2983           0 :         int debug = ifp->if_flags & IFF_DEBUG;
    2984           0 :         struct in6_addr suggestaddr;
    2985           0 :         char addr[INET6_ADDRSTRLEN];
    2986             : 
    2987           0 :         len -= 4;
    2988             : 
    2989           0 :         if (debug)
    2990           0 :                 log(LOG_DEBUG, SPP_FMT "ipv6cp nak opts: ",
    2991           0 :                     SPP_ARGS(ifp));
    2992             : 
    2993           0 :         p = (void*) (h+1);
    2994           0 :         for (; len > 1; len -= p[1], p += p[1]) {
    2995           0 :                 if (p[1] < 2 || p[1] > len)
    2996           0 :                         return;
    2997           0 :                 if (debug)
    2998           0 :                         addlog("%s ", sppp_ipv6cp_opt_name(*p));
    2999           0 :                 switch (*p) {
    3000             :                 case IPV6CP_OPT_IFID:
    3001             :                         /*
    3002             :                          * Peer doesn't like our local ifid.  See
    3003             :                          * if we can do something for him.  We'll drop
    3004             :                          * him our address then.
    3005             :                          */
    3006           0 :                         if (len < 10 || p[1] != 10)
    3007             :                                 break;
    3008           0 :                         sp->ipv6cp.flags |= IPV6CP_MYIFID_DYN;
    3009           0 :                         memset(&suggestaddr, 0, sizeof(suggestaddr));
    3010           0 :                         bcopy(&p[2], &suggestaddr.s6_addr[8], 8);
    3011           0 :                         if (IN6_IS_ADDR_UNSPECIFIED(&suggestaddr) ||
    3012           0 :                             (sp->ipv6cp.flags & IPV6CP_MYIFID_SEEN)) {
    3013             :                                 /*
    3014             :                                  * The peer didn't suggest anything,
    3015             :                                  * or wants us to change a previously
    3016             :                                  * suggested address.
    3017             :                                  * Configure a new address for us.
    3018             :                                  */
    3019           0 :                                 sppp_suggest_ip6_addr(sp, &suggestaddr);
    3020           0 :                                 sppp_set_ip6_addr(sp, &suggestaddr, NULL);
    3021           0 :                                 sp->ipv6cp.flags &= ~IPV6CP_MYIFID_SEEN;
    3022           0 :                         } else {
    3023             :                                 /* Configure address suggested by peer. */
    3024           0 :                                 suggestaddr.s6_addr16[0] = htons(0xfe80);
    3025           0 :                                 sp->ipv6cp.opts |= (1 << IPV6CP_OPT_IFID);
    3026           0 :                                 if (debug)
    3027           0 :                                         addlog(" [suggestaddr %s]",
    3028           0 :                                             inet_ntop(AF_INET6, &suggestaddr,
    3029           0 :                                                 addr, sizeof(addr)));
    3030           0 :                                 sppp_set_ip6_addr(sp, &suggestaddr, NULL);
    3031           0 :                                 if (debug)
    3032           0 :                                         addlog(" [agree]");
    3033           0 :                                 sp->ipv6cp.flags |= IPV6CP_MYIFID_SEEN;
    3034             :                         }
    3035             :                         break;
    3036             : #ifdef notyet
    3037             :                 case IPV6CP_OPT_COMPRESS:
    3038             :                         /*
    3039             :                          * Peer wants different compression parameters.
    3040             :                          */
    3041             :                         break;
    3042             : #endif
    3043             :                 }
    3044             :         }
    3045           0 :         if (debug)
    3046           0 :                 addlog("\n");
    3047           0 : }
    3048             : 
    3049             : void
    3050           0 : sppp_ipv6cp_tlu(struct sppp *sp)
    3051             : {
    3052           0 : }
    3053             : 
    3054             : void
    3055           0 : sppp_ipv6cp_tld(struct sppp *sp)
    3056             : {
    3057           0 : }
    3058             : 
    3059             : void
    3060           0 : sppp_ipv6cp_tls(struct sppp *sp)
    3061             : {
    3062             :         /* indicate to LCP that it must stay alive */
    3063           0 :         sp->lcp.protos |= (1 << IDX_IPV6CP);
    3064           0 : }
    3065             : 
    3066             : void
    3067           0 : sppp_ipv6cp_tlf(struct sppp *sp)
    3068             : {
    3069             :         /* we no longer need LCP */
    3070           0 :         sp->lcp.protos &= ~(1 << IDX_IPV6CP);
    3071           0 :         sppp_lcp_check_and_close(sp);
    3072           0 : }
    3073             : 
    3074             : void
    3075           0 : sppp_ipv6cp_scr(struct sppp *sp)
    3076             : {
    3077           0 :         char opt[10 /* ifid */ + 4 /* compression, minimum */];
    3078           0 :         struct in6_addr ouraddr;
    3079             :         int i = 0;
    3080             : 
    3081           0 :         if (sp->ipv6cp.opts & (1 << IPV6CP_OPT_IFID)) {
    3082           0 :                 if (sp->ipv6cp.flags & IPV6CP_MYIFID_DYN)
    3083           0 :                         ouraddr = sp->ipv6cp.req_ifid.ifra_addr.sin6_addr;
    3084             :                 else
    3085           0 :                         sppp_get_ip6_addrs(sp, &ouraddr, NULL, NULL);
    3086           0 :                 opt[i++] = IPV6CP_OPT_IFID;
    3087           0 :                 opt[i++] = 10;
    3088           0 :                 bcopy(&ouraddr.s6_addr[8], &opt[i], 8);
    3089             :                 i += 8;
    3090           0 :         }
    3091             : 
    3092             : #ifdef notyet
    3093             :         if (sp->ipv6cp.opts & (1 << IPV6CP_OPT_COMPRESSION)) {
    3094             :                 opt[i++] = IPV6CP_OPT_COMPRESSION;
    3095             :                 opt[i++] = 4;
    3096             :                 opt[i++] = 0;   /* TBD */
    3097             :                 opt[i++] = 0;   /* TBD */
    3098             :                 /* variable length data may follow */
    3099             :         }
    3100             : #endif
    3101             : 
    3102           0 :         sp->confid[IDX_IPV6CP] = ++sp->pp_seq;
    3103           0 :         sppp_cp_send(sp, PPP_IPV6CP, CONF_REQ, sp->confid[IDX_IPV6CP], i, opt);
    3104           0 : }
    3105             : #else /*INET6*/
    3106             : void
    3107             : sppp_ipv6cp_init(struct sppp *sp)
    3108             : {
    3109             : }
    3110             : 
    3111             : void
    3112             : sppp_ipv6cp_destroy(struct sppp *sp)
    3113             : {
    3114             : }
    3115             : 
    3116             : void
    3117             : sppp_ipv6cp_up(struct sppp *sp)
    3118             : {
    3119             : }
    3120             : 
    3121             : void
    3122             : sppp_ipv6cp_down(struct sppp *sp)
    3123             : {
    3124             : }
    3125             : 
    3126             : void
    3127             : sppp_ipv6cp_open(struct sppp *sp)
    3128             : {
    3129             : }
    3130             : 
    3131             : void
    3132             : sppp_ipv6cp_close(struct sppp *sp)
    3133             : {
    3134             : }
    3135             : 
    3136             : void
    3137             : sppp_ipv6cp_TO(void *sp)
    3138             : {
    3139             : }
    3140             : 
    3141             : int
    3142             : sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h,
    3143             :                 int len)
    3144             : {
    3145             :         return 0;
    3146             : }
    3147             : 
    3148             : void
    3149             : sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h,
    3150             :                     int len)
    3151             : {
    3152             : }
    3153             : 
    3154             : void
    3155             : sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h,
    3156             :                     int len)
    3157             : {
    3158             : }
    3159             : 
    3160             : void
    3161             : sppp_ipv6cp_tlu(struct sppp *sp)
    3162             : {
    3163             : }
    3164             : 
    3165             : void
    3166             : sppp_ipv6cp_tld(struct sppp *sp)
    3167             : {
    3168             : }
    3169             : 
    3170             : void
    3171             : sppp_ipv6cp_tls(struct sppp *sp)
    3172             : {
    3173             : }
    3174             : 
    3175             : void
    3176             : sppp_ipv6cp_tlf(struct sppp *sp)
    3177             : {
    3178             : }
    3179             : 
    3180             : void
    3181             : sppp_ipv6cp_scr(struct sppp *sp)
    3182             : {
    3183             : }
    3184             : #endif /*INET6*/
    3185             : 
    3186             : /*
    3187             :  *--------------------------------------------------------------------------*
    3188             :  *                                                                          *
    3189             :  *                        The CHAP implementation.                          *
    3190             :  *                                                                          *
    3191             :  *--------------------------------------------------------------------------*
    3192             :  */
    3193             : 
    3194             : /*
    3195             :  * The authentication protocols don't employ a full-fledged state machine as
    3196             :  * the control protocols do, since they do have Open and Close events, but
    3197             :  * not Up and Down, nor are they explicitly terminated.  Also, use of the
    3198             :  * authentication protocols may be different in both directions (this makes
    3199             :  * sense, think of a machine that never accepts incoming calls but only
    3200             :  * calls out, it doesn't require the called party to authenticate itself).
    3201             :  *
    3202             :  * Our state machine for the local authentication protocol (we are requesting
    3203             :  * the peer to authenticate) looks like:
    3204             :  *
    3205             :  *                                                  RCA-
    3206             :  *            +--------------------------------------------+
    3207             :  *            V                                     scn,tld|
    3208             :  *        +--------+                           Close   +---------+ RCA+
    3209             :  *        |        |<----------------------------------|      |------+
    3210             :  *   +--->| Closed |                         TO*    | Opened  | sca  |
    3211             :  *   |    |        |-----+                     +-------|         |<-----+
    3212             :  *   |    +--------+ irc |                     |       +---------+
    3213             :  *   |      ^            |                     |           ^
    3214             :  *   |      |            |                     |           |
    3215             :  *   |      |            |                     |           |
    3216             :  *   |   TO-|            |                     |           |
    3217             :  *   |      |tld  TO+    V                     |           |
    3218             :  *   |      |   +------->+                  |           |
    3219             :  *   |      |   |        |                     |           |
    3220             :  *   |    +--------+     V                     |           |
    3221             :  *   |    |        |<----+<--------------------+     |
    3222             :  *   |    | Req-   | scr                                   |
    3223             :  *   |    | Sent   |                                       |
    3224             :  *   |    |        |                                       |
    3225             :  *   |    +--------+                                       |
    3226             :  *   | RCA- |   | RCA+                                     |
    3227             :  *   +------+   +------------------------------------------+
    3228             :  *   scn,tld      sca,irc,ict,tlu
    3229             :  *
    3230             :  *
    3231             :  *   with:
    3232             :  *
    3233             :  *      Open:   LCP reached authentication phase
    3234             :  *      Close:  LCP reached terminate phase
    3235             :  *
    3236             :  *      RCA+:   received reply (pap-req, chap-response), acceptable
    3237             :  *      RCN:    received reply (pap-req, chap-response), not acceptable
    3238             :  *      TO+:    timeout with restart counter >= 0
    3239             :  *      TO-:    timeout with restart counter < 0
    3240             :  *      TO*:    reschedule timeout for CHAP
    3241             :  *
    3242             :  *      scr:    send request packet (none for PAP, chap-challenge)
    3243             :  *      sca:    send ack packet (pap-ack, chap-success)
    3244             :  *      scn:    send nak packet (pap-nak, chap-failure)
    3245             :  *      ict:    initialize re-challenge timer (CHAP only)
    3246             :  *
    3247             :  *      tlu:    this-layer-up, LCP reaches network phase
    3248             :  *      tld:    this-layer-down, LCP enters terminate phase
    3249             :  *
    3250             :  * Note that in CHAP mode, after sending a new challenge, while the state
    3251             :  * automaton falls back into Req-Sent state, it doesn't signal a tld
    3252             :  * event to LCP, so LCP remains in network phase.  Only after not getting
    3253             :  * any response (or after getting an unacceptable response), CHAP closes,
    3254             :  * causing LCP to enter terminate phase.
    3255             :  *
    3256             :  * With PAP, there is no initial request that can be sent.  The peer is
    3257             :  * expected to send one based on the successful negotiation of PAP as
    3258             :  * the authentication protocol during the LCP option negotiation.
    3259             :  *
    3260             :  * Incoming authentication protocol requests (remote requests
    3261             :  * authentication, we are peer) don't employ a state machine at all,
    3262             :  * they are simply answered.  Some peers [Ascend P50 firmware rev
    3263             :  * 4.50] react allergically when sending IPCP requests while they are
    3264             :  * still in authentication phase (thereby violating the standard that
    3265             :  * demands that these NCP packets are to be discarded), so we keep
    3266             :  * track of the peer demanding us to authenticate, and only proceed to
    3267             :  * phase network once we've seen a positive acknowledge for the
    3268             :  * authentication.
    3269             :  */
    3270             : 
    3271             : /*
    3272             :  * Handle incoming CHAP packets.
    3273             :  */
    3274             : void
    3275           0 : sppp_chap_input(struct sppp *sp, struct mbuf *m)
    3276             : {
    3277           0 :         STDDCL;
    3278             :         struct lcp_header *h;
    3279             :         int len, x;
    3280           0 :         u_char *value, *name, digest[AUTHCHALEN], dsize;
    3281             :         int value_len, name_len;
    3282           0 :         MD5_CTX ctx;
    3283             : 
    3284           0 :         len = m->m_pkthdr.len;
    3285           0 :         if (len < 4) {
    3286           0 :                 if (debug)
    3287           0 :                         log(LOG_DEBUG,
    3288             :                             SPP_FMT "chap invalid packet length: %d bytes\n",
    3289           0 :                             SPP_ARGS(ifp), len);
    3290           0 :                 return;
    3291             :         }
    3292           0 :         h = mtod (m, struct lcp_header*);
    3293           0 :         if (len > ntohs (h->len))
    3294           0 :                 len = ntohs (h->len);
    3295             : 
    3296           0 :         switch (h->type) {
    3297             :         /* challenge, failure and success are his authproto */
    3298             :         case CHAP_CHALLENGE:
    3299           0 :                 value = 1 + (u_char*)(h+1);
    3300           0 :                 value_len = value[-1];
    3301           0 :                 name = value + value_len;
    3302           0 :                 name_len = len - value_len - 5;
    3303           0 :                 if (name_len < 0) {
    3304           0 :                         if (debug) {
    3305           0 :                                 log(LOG_DEBUG,
    3306             :                                     SPP_FMT "chap corrupted challenge "
    3307             :                                     "<%s id=0x%x len=%d",
    3308           0 :                                     SPP_ARGS(ifp),
    3309           0 :                                     sppp_auth_type_name(PPP_CHAP, h->type),
    3310           0 :                                     h->ident, ntohs(h->len));
    3311           0 :                                 if (len > 4)
    3312           0 :                                         sppp_print_bytes((u_char*) (h+1), len-4);
    3313           0 :                                 addlog(">\n");
    3314           0 :                         }
    3315             :                         break;
    3316             :                 }
    3317             : 
    3318           0 :                 if (debug) {
    3319           0 :                         log(LOG_DEBUG,
    3320             :                             SPP_FMT "chap input <%s id=0x%x len=%d name=",
    3321           0 :                             SPP_ARGS(ifp),
    3322           0 :                             sppp_auth_type_name(PPP_CHAP, h->type), h->ident,
    3323           0 :                             ntohs(h->len));
    3324           0 :                         sppp_print_string((char*) name, name_len);
    3325           0 :                         addlog(" value-size=%d value=", value_len);
    3326           0 :                         sppp_print_bytes(value, value_len);
    3327           0 :                         addlog(">\n");
    3328           0 :                 }
    3329             : 
    3330             :                 /* Compute reply value. */
    3331           0 :                 MD5Init(&ctx);
    3332           0 :                 MD5Update(&ctx, &h->ident, 1);
    3333           0 :                 MD5Update(&ctx, sp->myauth.secret, strlen(sp->myauth.secret));
    3334           0 :                 MD5Update(&ctx, value, value_len);
    3335           0 :                 MD5Final(digest, &ctx);
    3336           0 :                 dsize = sizeof digest;
    3337             : 
    3338           0 :                 sppp_auth_send(&chap, sp, CHAP_RESPONSE, h->ident,
    3339             :                                sizeof dsize, (const char *)&dsize,
    3340             :                                sizeof digest, digest,
    3341           0 :                                strlen(sp->myauth.name),
    3342           0 :                                sp->myauth.name,
    3343             :                                0);
    3344           0 :                 break;
    3345             : 
    3346             :         case CHAP_SUCCESS:
    3347           0 :                 if (debug) {
    3348           0 :                         log(LOG_DEBUG, SPP_FMT "chap success",
    3349           0 :                             SPP_ARGS(ifp));
    3350           0 :                         if (len > 4) {
    3351           0 :                                 addlog(": ");
    3352           0 :                                 sppp_print_string((char*)(h + 1), len - 4);
    3353           0 :                         }
    3354           0 :                         addlog("\n");
    3355           0 :                 }
    3356           0 :                 x = splnet();
    3357           0 :                 sp->pp_flags &= ~PP_NEEDAUTH;
    3358           0 :                 if (sp->myauth.proto == PPP_CHAP &&
    3359           0 :                     (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) &&
    3360           0 :                     (sp->lcp.protos & (1 << IDX_CHAP)) == 0) {
    3361             :                         /*
    3362             :                          * We are authenticator for CHAP but didn't
    3363             :                          * complete yet.  Leave it to tlu to proceed
    3364             :                          * to network phase.
    3365             :                          */
    3366           0 :                         splx(x);
    3367           0 :                         break;
    3368             :                 }
    3369           0 :                 splx(x);
    3370           0 :                 sppp_phase_network(sp);
    3371           0 :                 break;
    3372             : 
    3373             :         case CHAP_FAILURE:
    3374           0 :                 if (debug) {
    3375           0 :                         log(LOG_INFO, SPP_FMT "chap failure",
    3376             :                             SPP_ARGS(ifp));
    3377           0 :                         if (len > 4) {
    3378           0 :                                 addlog(": ");
    3379           0 :                                 sppp_print_string((char*)(h + 1), len - 4);
    3380           0 :                         }
    3381           0 :                         addlog("\n");
    3382           0 :                 } else
    3383           0 :                         log(LOG_INFO, SPP_FMT "chap failure\n",
    3384             :                             SPP_ARGS(ifp));
    3385             :                 /* await LCP shutdown by authenticator */
    3386             :                 break;
    3387             : 
    3388             :         /* response is my authproto */
    3389             :         case CHAP_RESPONSE:
    3390           0 :                 value = 1 + (u_char*)(h+1);
    3391           0 :                 value_len = value[-1];
    3392           0 :                 name = value + value_len;
    3393           0 :                 name_len = len - value_len - 5;
    3394           0 :                 if (name_len < 0) {
    3395           0 :                         if (debug) {
    3396           0 :                                 log(LOG_DEBUG,
    3397             :                                     SPP_FMT "chap corrupted response "
    3398             :                                     "<%s id=0x%x len=%d",
    3399           0 :                                     SPP_ARGS(ifp),
    3400           0 :                                     sppp_auth_type_name(PPP_CHAP, h->type),
    3401           0 :                                     h->ident, ntohs(h->len));
    3402           0 :                                 if (len > 4)
    3403           0 :                                         sppp_print_bytes((u_char*)(h+1), len-4);
    3404           0 :                                 addlog(">\n");
    3405           0 :                         }
    3406             :                         break;
    3407             :                 }
    3408           0 :                 if (h->ident != sp->confid[IDX_CHAP]) {
    3409           0 :                         if (debug)
    3410           0 :                                 log(LOG_DEBUG,
    3411             :                                     SPP_FMT "chap dropping response for old ID "
    3412             :                                     "(got %d, expected %d)\n",
    3413           0 :                                     SPP_ARGS(ifp),
    3414             :                                     h->ident, sp->confid[IDX_CHAP]);
    3415             :                         break;
    3416             :                 }
    3417           0 :                 if (name_len != strlen(sp->hisauth.name)
    3418           0 :                     || bcmp(name, sp->hisauth.name, name_len) != 0) {
    3419           0 :                         log(LOG_INFO, SPP_FMT "chap response, his name ",
    3420           0 :                             SPP_ARGS(ifp));
    3421           0 :                         sppp_print_string(name, name_len);
    3422           0 :                         addlog(" != expected ");
    3423           0 :                         sppp_print_string(sp->hisauth.name,
    3424           0 :                             strlen(sp->hisauth.name));
    3425           0 :                         addlog("\n");
    3426           0 :                 }
    3427           0 :                 if (debug) {
    3428           0 :                         log(LOG_DEBUG, SPP_FMT "chap input(%s) "
    3429             :                             "<%s id=0x%x len=%d name=",
    3430           0 :                             SPP_ARGS(ifp),
    3431           0 :                             sppp_state_name(sp->state[IDX_CHAP]),
    3432           0 :                             sppp_auth_type_name(PPP_CHAP, h->type),
    3433           0 :                             h->ident, ntohs (h->len));
    3434           0 :                         sppp_print_string((char*)name, name_len);
    3435           0 :                         addlog(" value-size=%d value=", value_len);
    3436           0 :                         sppp_print_bytes(value, value_len);
    3437           0 :                         addlog(">\n");
    3438           0 :                 }
    3439           0 :                 if (value_len != AUTHCHALEN) {
    3440           0 :                         if (debug)
    3441           0 :                                 log(LOG_DEBUG,
    3442             :                                     SPP_FMT "chap bad hash value length: "
    3443             :                                     "%d bytes, should be %d\n",
    3444           0 :                                     SPP_ARGS(ifp), value_len,
    3445             :                                     AUTHCHALEN);
    3446             :                         break;
    3447             :                 }
    3448             : 
    3449           0 :                 MD5Init(&ctx);
    3450           0 :                 MD5Update(&ctx, &h->ident, 1);
    3451           0 :                 MD5Update(&ctx, sp->hisauth.secret, strlen(sp->hisauth.secret));
    3452           0 :                 MD5Update(&ctx, sp->chap_challenge, AUTHCHALEN);
    3453           0 :                 MD5Final(digest, &ctx);
    3454             : 
    3455             : #define FAILMSG "Failed..."
    3456             : #define SUCCMSG "Welcome!"
    3457             : 
    3458           0 :                 if (value_len != sizeof digest ||
    3459           0 :                     timingsafe_bcmp(digest, value, value_len) != 0) {
    3460             :                         /* action scn, tld */
    3461           0 :                         sppp_auth_send(&chap, sp, CHAP_FAILURE, h->ident,
    3462             :                                        sizeof(FAILMSG) - 1, (u_char *)FAILMSG,
    3463             :                                        0);
    3464           0 :                         chap.tld(sp);
    3465           0 :                         break;
    3466             :                 }
    3467             :                 /* action sca, perhaps tlu */
    3468           0 :                 if (sp->state[IDX_CHAP] == STATE_REQ_SENT ||
    3469           0 :                     sp->state[IDX_CHAP] == STATE_OPENED)
    3470           0 :                         sppp_auth_send(&chap, sp, CHAP_SUCCESS, h->ident,
    3471             :                                        sizeof(SUCCMSG) - 1, (u_char *)SUCCMSG,
    3472             :                                        0);
    3473           0 :                 if (sp->state[IDX_CHAP] == STATE_REQ_SENT) {
    3474           0 :                         sppp_cp_change_state(&chap, sp, STATE_OPENED);
    3475           0 :                         chap.tlu(sp);
    3476           0 :                 }
    3477             :                 break;
    3478             : 
    3479             :         default:
    3480             :                 /* Unknown CHAP packet type -- ignore. */
    3481           0 :                 if (debug) {
    3482           0 :                         log(LOG_DEBUG, SPP_FMT "chap unknown input(%s) "
    3483             :                             "<0x%x id=0x%xh len=%d",
    3484           0 :                             SPP_ARGS(ifp),
    3485           0 :                             sppp_state_name(sp->state[IDX_CHAP]),
    3486           0 :                             h->type, h->ident, ntohs(h->len));
    3487           0 :                         if (len > 4)
    3488           0 :                                 sppp_print_bytes((u_char*)(h+1), len-4);
    3489           0 :                         addlog(">\n");
    3490           0 :                 }
    3491             :                 break;
    3492             : 
    3493             :         }
    3494           0 : }
    3495             : 
    3496             : void
    3497           0 : sppp_chap_init(struct sppp *sp)
    3498             : {
    3499             :         /* Chap doesn't have STATE_INITIAL at all. */
    3500           0 :         sp->state[IDX_CHAP] = STATE_CLOSED;
    3501           0 :         sp->fail_counter[IDX_CHAP] = 0;
    3502           0 : }
    3503             : 
    3504             : void
    3505           0 : sppp_chap_open(struct sppp *sp)
    3506             : {
    3507           0 :         if (sp->myauth.proto == PPP_CHAP &&
    3508           0 :             (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) != 0) {
    3509             :                 /* we are authenticator for CHAP, start it */
    3510           0 :                 chap.scr(sp);
    3511           0 :                 sp->rst_counter[IDX_CHAP] = sp->lcp.max_configure;
    3512           0 :                 sppp_cp_change_state(&chap, sp, STATE_REQ_SENT);
    3513           0 :         }
    3514             :         /* nothing to be done if we are peer, await a challenge */
    3515           0 : }
    3516             : 
    3517             : void
    3518           0 : sppp_chap_close(struct sppp *sp)
    3519             : {
    3520           0 :         if (sp->state[IDX_CHAP] != STATE_CLOSED)
    3521           0 :                 sppp_cp_change_state(&chap, sp, STATE_CLOSED);
    3522           0 : }
    3523             : 
    3524             : void
    3525           0 : sppp_chap_TO(void *cookie)
    3526             : {
    3527           0 :         struct sppp *sp = (struct sppp *)cookie;
    3528           0 :         STDDCL;
    3529             :         int s;
    3530             : 
    3531           0 :         s = splnet();
    3532           0 :         if (debug)
    3533           0 :                 log(LOG_DEBUG, SPP_FMT "chap TO(%s) rst_counter = %d\n",
    3534           0 :                     SPP_ARGS(ifp),
    3535           0 :                     sppp_state_name(sp->state[IDX_CHAP]),
    3536           0 :                     sp->rst_counter[IDX_CHAP]);
    3537             : 
    3538           0 :         if (--sp->rst_counter[IDX_CHAP] < 0)
    3539             :                 /* TO- event */
    3540           0 :                 switch (sp->state[IDX_CHAP]) {
    3541             :                 case STATE_REQ_SENT:
    3542           0 :                         chap.tld(sp);
    3543           0 :                         sppp_cp_change_state(&chap, sp, STATE_CLOSED);
    3544           0 :                         break;
    3545             :                 }
    3546             :         else
    3547             :                 /* TO+ (or TO*) event */
    3548           0 :                 switch (sp->state[IDX_CHAP]) {
    3549             :                 case STATE_OPENED:
    3550             :                         /* TO* event */
    3551           0 :                         sp->rst_counter[IDX_CHAP] = sp->lcp.max_configure;
    3552             :                         /* FALLTHROUGH */
    3553             :                 case STATE_REQ_SENT:
    3554           0 :                         chap.scr(sp);
    3555             :                         /* sppp_cp_change_state() will restart the timer */
    3556           0 :                         sppp_cp_change_state(&chap, sp, STATE_REQ_SENT);
    3557           0 :                         break;
    3558             :                 }
    3559             : 
    3560           0 :         splx(s);
    3561           0 : }
    3562             : 
    3563             : void
    3564           0 : sppp_chap_tlu(struct sppp *sp)
    3565             : {
    3566           0 :         STDDCL;
    3567             :         int i = 0, x;
    3568             : 
    3569             :         i = 0;
    3570           0 :         sp->rst_counter[IDX_CHAP] = sp->lcp.max_configure;
    3571             : 
    3572             :         /*
    3573             :          * Some broken CHAP implementations (Conware CoNet, firmware
    3574             :          * 4.0.?) don't want to re-authenticate their CHAP once the
    3575             :          * initial challenge-response exchange has taken place.
    3576             :          * Provide for an option to avoid rechallenges.
    3577             :          */
    3578           0 :         if ((sp->hisauth.flags & AUTHFLAG_NORECHALLENGE) == 0) {
    3579             :                 /*
    3580             :                  * Compute the re-challenge timeout.  This will yield
    3581             :                  * a number between 300 and 810 seconds.
    3582             :                  */
    3583           0 :                 i = 300 + (arc4random() & 0x01fe);
    3584             : 
    3585           0 :                 timeout_add_sec(&sp->ch[IDX_CHAP], i);
    3586           0 :         }
    3587             : 
    3588           0 :         if (debug) {
    3589           0 :                 log(LOG_DEBUG,
    3590             :                     SPP_FMT "chap %s, ",
    3591           0 :                     SPP_ARGS(ifp),
    3592           0 :                     sp->pp_phase == PHASE_NETWORK? "reconfirmed": "tlu");
    3593           0 :                 if ((sp->hisauth.flags & AUTHFLAG_NORECHALLENGE) == 0)
    3594           0 :                         addlog("next re-challenge in %d seconds\n", i);
    3595             :                 else
    3596           0 :                         addlog("re-challenging suppressed\n");
    3597             :         }
    3598             : 
    3599           0 :         x = splnet();
    3600             :         /* indicate to LCP that we need to be closed down */
    3601           0 :         sp->lcp.protos |= (1 << IDX_CHAP);
    3602             : 
    3603           0 :         if (sp->pp_flags & PP_NEEDAUTH) {
    3604             :                 /*
    3605             :                  * Remote is authenticator, but his auth proto didn't
    3606             :                  * complete yet.  Defer the transition to network
    3607             :                  * phase.
    3608             :                  */
    3609             :                 splx(x);
    3610           0 :                 return;
    3611             :         }
    3612             :         splx(x);
    3613             : 
    3614             :         /*
    3615             :          * If we are already in phase network, we are done here.  This
    3616             :          * is the case if this is a dummy tlu event after a re-challenge.
    3617             :          */
    3618           0 :         if (sp->pp_phase != PHASE_NETWORK)
    3619           0 :                 sppp_phase_network(sp);
    3620           0 : }
    3621             : 
    3622             : void
    3623           0 : sppp_chap_tld(struct sppp *sp)
    3624             : {
    3625           0 :         STDDCL;
    3626             : 
    3627           0 :         if (debug)
    3628           0 :                 log(LOG_DEBUG, SPP_FMT "chap tld\n", SPP_ARGS(ifp));
    3629           0 :         UNTIMEOUT(chap.TO, (void *)sp, sp->ch[IDX_CHAP]);
    3630           0 :         sp->lcp.protos &= ~(1 << IDX_CHAP);
    3631             : 
    3632           0 :         lcp.Close(sp);
    3633           0 : }
    3634             : 
    3635             : void
    3636           0 : sppp_chap_scr(struct sppp *sp)
    3637             : {
    3638           0 :         u_char clen;
    3639             : 
    3640             :         /* Compute random challenge. */
    3641           0 :         arc4random_buf(sp->chap_challenge, sizeof(sp->chap_challenge));
    3642           0 :         clen = AUTHCHALEN;
    3643             : 
    3644           0 :         sp->confid[IDX_CHAP] = ++sp->pp_seq;
    3645             : 
    3646           0 :         sppp_auth_send(&chap, sp, CHAP_CHALLENGE, sp->confid[IDX_CHAP],
    3647             :                        sizeof clen, (const char *)&clen,
    3648             :                        (size_t)AUTHCHALEN, sp->chap_challenge,
    3649           0 :                        strlen(sp->myauth.name),
    3650           0 :                        sp->myauth.name,
    3651             :                        0);
    3652           0 : }
    3653             : /*
    3654             :  *--------------------------------------------------------------------------*
    3655             :  *                                                                          *
    3656             :  *                        The PAP implementation.                           *
    3657             :  *                                                                          *
    3658             :  *--------------------------------------------------------------------------*
    3659             :  */
    3660             : /*
    3661             :  * For PAP, we need to keep a little state also if we are the peer, not the
    3662             :  * authenticator.  This is since we don't get a request to authenticate, but
    3663             :  * have to repeatedly authenticate ourself until we got a response (or the
    3664             :  * retry counter is expired).
    3665             :  */
    3666             : 
    3667             : /*
    3668             :  * Handle incoming PAP packets.  */
    3669             : void
    3670           0 : sppp_pap_input(struct sppp *sp, struct mbuf *m)
    3671             : {
    3672           0 :         STDDCL;
    3673             :         struct lcp_header *h;
    3674             :         int len, x;
    3675           0 :         u_char *name, *passwd, mlen;
    3676             :         int name_len, passwd_len;
    3677             : 
    3678           0 :         len = m->m_pkthdr.len;
    3679           0 :         if (len < 5) {
    3680           0 :                 if (debug)
    3681           0 :                         log(LOG_DEBUG,
    3682             :                             SPP_FMT "pap invalid packet length: %d bytes\n",
    3683           0 :                             SPP_ARGS(ifp), len);
    3684           0 :                 return;
    3685             :         }
    3686           0 :         h = mtod (m, struct lcp_header*);
    3687           0 :         if (len > ntohs (h->len))
    3688           0 :                 len = ntohs (h->len);
    3689           0 :         switch (h->type) {
    3690             :         /* PAP request is my authproto */
    3691             :         case PAP_REQ:
    3692           0 :                 name = 1 + (u_char*)(h+1);
    3693           0 :                 name_len = name[-1];
    3694           0 :                 passwd = name + name_len + 1;
    3695           0 :                 if (name_len > len - 6 ||
    3696           0 :                     (passwd_len = passwd[-1]) > len - 6 - name_len) {
    3697           0 :                         if (debug) {
    3698           0 :                                 log(LOG_DEBUG, SPP_FMT "pap corrupted input "
    3699             :                                     "<%s id=0x%x len=%d",
    3700           0 :                                     SPP_ARGS(ifp),
    3701           0 :                                     sppp_auth_type_name(PPP_PAP, h->type),
    3702           0 :                                     h->ident, ntohs(h->len));
    3703           0 :                                 if (len > 4)
    3704           0 :                                         sppp_print_bytes((u_char*)(h+1), len-4);
    3705           0 :                                 addlog(">\n");
    3706           0 :                         }
    3707             :                         break;
    3708             :                 }
    3709           0 :                 if (debug) {
    3710           0 :                         log(LOG_DEBUG, SPP_FMT "pap input(%s) "
    3711             :                             "<%s id=0x%x len=%d name=",
    3712           0 :                             SPP_ARGS(ifp),
    3713           0 :                             sppp_state_name(sp->state[IDX_PAP]),
    3714           0 :                             sppp_auth_type_name(PPP_PAP, h->type),
    3715           0 :                             h->ident, ntohs(h->len));
    3716           0 :                         sppp_print_string((char*)name, name_len);
    3717           0 :                         addlog(" passwd=");
    3718           0 :                         sppp_print_string((char*)passwd, passwd_len);
    3719           0 :                         addlog(">\n");
    3720           0 :                 }
    3721           0 :                 if (name_len > AUTHMAXLEN ||
    3722             :                     passwd_len > AUTHMAXLEN ||
    3723           0 :                     bcmp(name, sp->hisauth.name, name_len) != 0 ||
    3724           0 :                     bcmp(passwd, sp->hisauth.secret, passwd_len) != 0) {
    3725             :                         /* action scn, tld */
    3726           0 :                         mlen = sizeof(FAILMSG) - 1;
    3727           0 :                         sppp_auth_send(&pap, sp, PAP_NAK, h->ident,
    3728             :                                        sizeof mlen, (const char *)&mlen,
    3729             :                                        sizeof(FAILMSG) - 1, (u_char *)FAILMSG,
    3730             :                                        0);
    3731           0 :                         pap.tld(sp);
    3732           0 :                         break;
    3733             :                 }
    3734             :                 /* action sca, perhaps tlu */
    3735           0 :                 if (sp->state[IDX_PAP] == STATE_REQ_SENT ||
    3736           0 :                     sp->state[IDX_PAP] == STATE_OPENED) {
    3737           0 :                         mlen = sizeof(SUCCMSG) - 1;
    3738           0 :                         sppp_auth_send(&pap, sp, PAP_ACK, h->ident,
    3739             :                                        sizeof mlen, (const char *)&mlen,
    3740             :                                        sizeof(SUCCMSG) - 1, (u_char *)SUCCMSG,
    3741             :                                        0);
    3742           0 :                 }
    3743           0 :                 if (sp->state[IDX_PAP] == STATE_REQ_SENT) {
    3744           0 :                         sppp_cp_change_state(&pap, sp, STATE_OPENED);
    3745           0 :                         pap.tlu(sp);
    3746           0 :                 }
    3747             :                 break;
    3748             : 
    3749             :         /* ack and nak are his authproto */
    3750             :         case PAP_ACK:
    3751           0 :                 UNTIMEOUT(sppp_pap_my_TO, (void *)sp, sp->pap_my_to_ch);
    3752           0 :                 if (debug) {
    3753           0 :                         log(LOG_DEBUG, SPP_FMT "pap success",
    3754           0 :                             SPP_ARGS(ifp));
    3755           0 :                         name_len = *((char *)h);
    3756           0 :                         if (len > 5 && name_len) {
    3757           0 :                                 addlog(": ");
    3758           0 :                                 sppp_print_string((char*)(h+1), name_len);
    3759           0 :                         }
    3760           0 :                         addlog("\n");
    3761           0 :                 }
    3762           0 :                 x = splnet();
    3763           0 :                 sp->pp_flags &= ~PP_NEEDAUTH;
    3764           0 :                 if (sp->myauth.proto == PPP_PAP &&
    3765           0 :                     (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) &&
    3766           0 :                     (sp->lcp.protos & (1 << IDX_PAP)) == 0) {
    3767             :                         /*
    3768             :                          * We are authenticator for PAP but didn't
    3769             :                          * complete yet.  Leave it to tlu to proceed
    3770             :                          * to network phase.
    3771             :                          */
    3772           0 :                         splx(x);
    3773           0 :                         break;
    3774             :                 }
    3775           0 :                 splx(x);
    3776           0 :                 sppp_phase_network(sp);
    3777           0 :                 break;
    3778             : 
    3779             :         case PAP_NAK:
    3780           0 :                 UNTIMEOUT(sppp_pap_my_TO, (void *)sp, sp->pap_my_to_ch);
    3781           0 :                 if (debug) {
    3782           0 :                         log(LOG_INFO, SPP_FMT "pap failure",
    3783             :                             SPP_ARGS(ifp));
    3784           0 :                         name_len = *((char *)h);
    3785           0 :                         if (len > 5 && name_len) {
    3786           0 :                                 addlog(": ");
    3787           0 :                                 sppp_print_string((char*)(h+1), name_len);
    3788           0 :                         }
    3789           0 :                         addlog("\n");
    3790           0 :                 } else
    3791           0 :                         log(LOG_INFO, SPP_FMT "pap failure\n",
    3792             :                             SPP_ARGS(ifp));
    3793             :                 /* await LCP shutdown by authenticator */
    3794             :                 break;
    3795             : 
    3796             :         default:
    3797             :                 /* Unknown PAP packet type -- ignore. */
    3798           0 :                 if (debug) {
    3799           0 :                         log(LOG_DEBUG, SPP_FMT "pap corrupted input "
    3800             :                             "<0x%x id=0x%x len=%d",
    3801           0 :                             SPP_ARGS(ifp),
    3802           0 :                             h->type, h->ident, ntohs(h->len));
    3803           0 :                         if (len > 4)
    3804           0 :                                 sppp_print_bytes((u_char*)(h+1), len-4);
    3805           0 :                         addlog(">\n");
    3806           0 :                 }
    3807             :                 break;
    3808             : 
    3809             :         }
    3810           0 : }
    3811             : 
    3812             : void
    3813           0 : sppp_pap_init(struct sppp *sp)
    3814             : {
    3815             :         /* PAP doesn't have STATE_INITIAL at all. */
    3816           0 :         sp->state[IDX_PAP] = STATE_CLOSED;
    3817           0 :         sp->fail_counter[IDX_PAP] = 0;
    3818           0 : }
    3819             : 
    3820             : void
    3821           0 : sppp_pap_open(struct sppp *sp)
    3822             : {
    3823           0 :         if (sp->hisauth.proto == PPP_PAP &&
    3824           0 :             (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) != 0) {
    3825             :                 /* we are authenticator for PAP, start our timer */
    3826           0 :                 sp->rst_counter[IDX_PAP] = sp->lcp.max_configure;
    3827           0 :                 sppp_cp_change_state(&pap, sp, STATE_REQ_SENT);
    3828           0 :         }
    3829           0 :         if (sp->myauth.proto == PPP_PAP) {
    3830             :                 /* we are peer, send a request, and start a timer */
    3831           0 :                 pap.scr(sp);
    3832           0 :                 timeout_add(&sp->pap_my_to_ch, sp->lcp.timeout);
    3833           0 :         }
    3834           0 : }
    3835             : 
    3836             : void
    3837           0 : sppp_pap_close(struct sppp *sp)
    3838             : {
    3839           0 :         if (sp->state[IDX_PAP] != STATE_CLOSED)
    3840           0 :                 sppp_cp_change_state(&pap, sp, STATE_CLOSED);
    3841           0 : }
    3842             : 
    3843             : /*
    3844             :  * That's the timeout routine if we are authenticator.  Since the
    3845             :  * authenticator is basically passive in PAP, we can't do much here.
    3846             :  */
    3847             : void
    3848           0 : sppp_pap_TO(void *cookie)
    3849             : {
    3850           0 :         struct sppp *sp = (struct sppp *)cookie;
    3851           0 :         STDDCL;
    3852             :         int s;
    3853             : 
    3854           0 :         s = splnet();
    3855           0 :         if (debug)
    3856           0 :                 log(LOG_DEBUG, SPP_FMT "pap TO(%s) rst_counter = %d\n",
    3857           0 :                     SPP_ARGS(ifp),
    3858           0 :                     sppp_state_name(sp->state[IDX_PAP]),
    3859           0 :                     sp->rst_counter[IDX_PAP]);
    3860             : 
    3861           0 :         if (--sp->rst_counter[IDX_PAP] < 0)
    3862             :                 /* TO- event */
    3863           0 :                 switch (sp->state[IDX_PAP]) {
    3864             :                 case STATE_REQ_SENT:
    3865           0 :                         pap.tld(sp);
    3866           0 :                         sppp_cp_change_state(&pap, sp, STATE_CLOSED);
    3867           0 :                         break;
    3868             :                 }
    3869             :         else
    3870             :                 /* TO+ event, not very much we could do */
    3871           0 :                 switch (sp->state[IDX_PAP]) {
    3872             :                 case STATE_REQ_SENT:
    3873             :                         /* sppp_cp_change_state() will restart the timer */
    3874           0 :                         sppp_cp_change_state(&pap, sp, STATE_REQ_SENT);
    3875           0 :                         break;
    3876             :                 }
    3877             : 
    3878           0 :         splx(s);
    3879           0 : }
    3880             : 
    3881             : /*
    3882             :  * That's the timeout handler if we are peer.  Since the peer is active,
    3883             :  * we need to retransmit our PAP request since it is apparently lost.
    3884             :  * XXX We should impose a max counter.
    3885             :  */
    3886             : void
    3887           0 : sppp_pap_my_TO(void *cookie)
    3888             : {
    3889           0 :         struct sppp *sp = (struct sppp *)cookie;
    3890           0 :         STDDCL;
    3891             : 
    3892           0 :         if (debug)
    3893           0 :                 log(LOG_DEBUG, SPP_FMT "pap peer TO\n",
    3894           0 :                     SPP_ARGS(ifp));
    3895             : 
    3896           0 :         pap.scr(sp);
    3897           0 : }
    3898             : 
    3899             : void
    3900           0 : sppp_pap_tlu(struct sppp *sp)
    3901             : {
    3902           0 :         STDDCL;
    3903             :         int x;
    3904             : 
    3905           0 :         sp->rst_counter[IDX_PAP] = sp->lcp.max_configure;
    3906             : 
    3907           0 :         if (debug)
    3908           0 :                 log(LOG_DEBUG, SPP_FMT "%s tlu\n",
    3909           0 :                     SPP_ARGS(ifp), pap.name);
    3910             : 
    3911           0 :         x = splnet();
    3912             :         /* indicate to LCP that we need to be closed down */
    3913           0 :         sp->lcp.protos |= (1 << IDX_PAP);
    3914             : 
    3915           0 :         if (sp->pp_flags & PP_NEEDAUTH) {
    3916             :                 /*
    3917             :                  * Remote is authenticator, but his auth proto didn't
    3918             :                  * complete yet.  Defer the transition to network
    3919             :                  * phase.
    3920             :                  */
    3921             :                 splx(x);
    3922           0 :                 return;
    3923             :         }
    3924             :         splx(x);
    3925           0 :         sppp_phase_network(sp);
    3926           0 : }
    3927             : 
    3928             : void
    3929           0 : sppp_pap_tld(struct sppp *sp)
    3930             : {
    3931           0 :         STDDCL;
    3932             : 
    3933           0 :         if (debug)
    3934           0 :                 log(LOG_DEBUG, SPP_FMT "pap tld\n", SPP_ARGS(ifp));
    3935           0 :         UNTIMEOUT(pap.TO, (void *)sp, sp->ch[IDX_PAP]);
    3936           0 :         UNTIMEOUT(sppp_pap_my_TO, (void *)sp, sp->pap_my_to_ch);
    3937           0 :         sp->lcp.protos &= ~(1 << IDX_PAP);
    3938             : 
    3939           0 :         lcp.Close(sp);
    3940           0 : }
    3941             : 
    3942             : void
    3943           0 : sppp_pap_scr(struct sppp *sp)
    3944             : {
    3945           0 :         u_char idlen, pwdlen;
    3946             : 
    3947           0 :         sp->confid[IDX_PAP] = ++sp->pp_seq;
    3948           0 :         pwdlen = strlen(sp->myauth.secret);
    3949           0 :         idlen = strlen(sp->myauth.name);
    3950             : 
    3951           0 :         sppp_auth_send(&pap, sp, PAP_REQ, sp->confid[IDX_PAP],
    3952             :                        sizeof idlen, (const char *)&idlen,
    3953           0 :                        (size_t)idlen, sp->myauth.name,
    3954             :                        sizeof pwdlen, (const char *)&pwdlen,
    3955           0 :                        (size_t)pwdlen, sp->myauth.secret,
    3956             :                        0);
    3957           0 : }
    3958             : /*
    3959             :  * Random miscellaneous functions.
    3960             :  */
    3961             : 
    3962             : /*
    3963             :  * Send a PAP or CHAP proto packet.
    3964             :  *
    3965             :  * Varadic function, each of the elements for the ellipsis is of type
    3966             :  * ``size_t mlen, const u_char *msg''.  Processing will stop iff
    3967             :  * mlen == 0.
    3968             :  */
    3969             : 
    3970             : void
    3971           0 : sppp_auth_send(const struct cp *cp, struct sppp *sp,
    3972             :                 unsigned int type, u_int id, ...)
    3973             : {
    3974           0 :         STDDCL;
    3975             :         struct lcp_header *lh;
    3976             :         struct mbuf *m;
    3977             :         u_char *p;
    3978             :         int len, s;
    3979             :         unsigned int mlen;
    3980             :         const char *msg;
    3981           0 :         va_list ap;
    3982             : 
    3983           0 :         MGETHDR (m, M_DONTWAIT, MT_DATA);
    3984           0 :         if (! m)
    3985           0 :                 return;
    3986           0 :         m->m_pkthdr.ph_ifidx = 0;
    3987           0 :         m->m_pkthdr.pf.prio = sp->pp_if.if_llprio;
    3988             : 
    3989           0 :         *mtod(m, u_int16_t *) = htons(cp->proto);
    3990           0 :         lh = (struct lcp_header *)(mtod(m, u_int8_t *) + 2);
    3991             : 
    3992           0 :         lh->type = type;
    3993           0 :         lh->ident = id;
    3994           0 :         p = (u_char*) (lh+1);
    3995             : 
    3996           0 :         va_start(ap, id);
    3997             :         len = 0;
    3998             : 
    3999           0 :         while ((mlen = (unsigned int)va_arg(ap, size_t)) != 0) {
    4000           0 :                 msg = va_arg(ap, const char *);
    4001           0 :                 len += mlen;
    4002           0 :                 if (len > MHLEN - PKTHDRLEN - LCP_HEADER_LEN) {
    4003           0 :                         va_end(ap);
    4004           0 :                         m_freem(m);
    4005           0 :                         return;
    4006             :                 }
    4007             : 
    4008           0 :                 bcopy(msg, p, mlen);
    4009           0 :                 p += mlen;
    4010             :         }
    4011           0 :         va_end(ap);
    4012             : 
    4013           0 :         m->m_pkthdr.len = m->m_len = PKTHDRLEN + LCP_HEADER_LEN + len;
    4014           0 :         lh->len = htons (LCP_HEADER_LEN + len);
    4015             : 
    4016           0 :         if (debug) {
    4017           0 :                 log(LOG_DEBUG, SPP_FMT "%s output <%s id=0x%x len=%d",
    4018           0 :                     SPP_ARGS(ifp), cp->name,
    4019           0 :                     sppp_auth_type_name(cp->proto, lh->type),
    4020           0 :                     lh->ident, ntohs(lh->len));
    4021           0 :                 if (len)
    4022           0 :                         sppp_print_bytes((u_char*) (lh+1), len);
    4023           0 :                 addlog(">\n");
    4024           0 :         }
    4025             : 
    4026           0 :         len = m->m_pkthdr.len + sp->pp_framebytes;
    4027           0 :         if (mq_enqueue(&sp->pp_cpq, m) != 0) {
    4028           0 :                 ifp->if_oerrors++;
    4029           0 :                 return;
    4030             :         }
    4031             : 
    4032           0 :         ifp->if_obytes += len;
    4033           0 :         s = splnet();
    4034           0 :         if_start(ifp);
    4035           0 :         splx(s);
    4036           0 : }
    4037             : 
    4038             : /*
    4039             :  * Send keepalive packets, every 10 seconds.
    4040             :  */
    4041             : void
    4042           0 : sppp_keepalive(void *dummy)
    4043             : {
    4044             :         struct sppp *sp;
    4045             :         int s;
    4046           0 :         struct timeval tv;
    4047             : 
    4048           0 :         NET_LOCK();
    4049           0 :         s = splnet();
    4050           0 :         getmicrouptime(&tv);
    4051           0 :         for (sp=spppq; sp; sp=sp->pp_next) {
    4052           0 :                 struct ifnet *ifp = &sp->pp_if;
    4053             : 
    4054             :                 /* Keepalive mode disabled or channel down? */
    4055           0 :                 if (! (sp->pp_flags & PP_KEEPALIVE) ||
    4056           0 :                     ! (ifp->if_flags & IFF_RUNNING))
    4057           0 :                         continue;
    4058             : 
    4059             :                 /* No keepalive if LCP not opened yet. */
    4060           0 :                 if (sp->pp_phase < PHASE_AUTHENTICATE)
    4061           0 :                         continue;
    4062             : 
    4063             :                 /* No echo reply, but maybe user data passed through? */
    4064           0 :                 if ((tv.tv_sec - sp->pp_last_receive) < NORECV_TIME) {
    4065           0 :                         sp->pp_alivecnt = 0;
    4066           0 :                         continue;
    4067             :                 }
    4068             : 
    4069           0 :                 if (sp->pp_alivecnt >= MAXALIVECNT) {
    4070             :                         /* No keepalive packets got.  Stop the interface. */
    4071           0 :                         if_down (ifp);
    4072           0 :                         mq_purge(&sp->pp_cpq);
    4073           0 :                         log(LOG_INFO, SPP_FMT "LCP keepalive timeout\n",
    4074           0 :                             SPP_ARGS(ifp));
    4075           0 :                         sp->pp_alivecnt = 0;
    4076             : 
    4077             :                         /* we are down, close all open protocols */
    4078           0 :                         lcp.Close(sp);
    4079             : 
    4080             :                         /* And now prepare LCP to reestablish the link,
    4081             :                          * if configured to do so. */
    4082           0 :                         sppp_cp_change_state(&lcp, sp, STATE_STOPPED);
    4083             : 
    4084             :                         /* Close connection immediately, completion of this
    4085             :                          * will summon the magic needed to reestablish it. */
    4086           0 :                         if (sp->pp_tlf)
    4087           0 :                                 sp->pp_tlf(sp);
    4088           0 :                         continue;
    4089             :                 }
    4090           0 :                 if (sp->pp_alivecnt < MAXALIVECNT)
    4091           0 :                         ++sp->pp_alivecnt;
    4092           0 :                 if (sp->pp_phase >= PHASE_AUTHENTICATE) {
    4093           0 :                         u_int32_t nmagic = htonl(sp->lcp.magic);
    4094           0 :                         sp->lcp.echoid = ++sp->pp_seq;
    4095           0 :                         sppp_cp_send (sp, PPP_LCP, ECHO_REQ,
    4096             :                                 sp->lcp.echoid, 4, &nmagic);
    4097           0 :                 }
    4098           0 :         }
    4099           0 :         splx(s);
    4100           0 :         NET_UNLOCK();
    4101           0 :         timeout_add_sec(&keepalive_ch, 10);
    4102           0 : }
    4103             : 
    4104             : /*
    4105             :  * Get both IP addresses.
    4106             :  */
    4107             : void
    4108           0 : sppp_get_ip_addrs(struct sppp *sp, u_int32_t *src, u_int32_t *dst,
    4109             :     u_int32_t *srcmask)
    4110             : {
    4111           0 :         struct ifnet *ifp = &sp->pp_if;
    4112             :         struct ifaddr *ifa;
    4113             :         struct sockaddr_in *si, *sm = 0;
    4114             :         u_int32_t ssrc, ddst;
    4115             : 
    4116             :         sm = NULL;
    4117             :         ssrc = ddst = 0;
    4118             :         /*
    4119             :          * Pick the first AF_INET address from the list,
    4120             :          * aliases don't make any sense on a p2p link anyway.
    4121             :          */
    4122             :         si = 0;
    4123           0 :         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
    4124             :         {
    4125           0 :                 if (ifa->ifa_addr->sa_family == AF_INET) {
    4126           0 :                         si = (struct sockaddr_in *)ifa->ifa_addr;
    4127           0 :                         sm = (struct sockaddr_in *)ifa->ifa_netmask;
    4128           0 :                         if (si)
    4129             :                                 break;
    4130             :                 }
    4131             :         }
    4132           0 :         if (ifa) {
    4133           0 :                 if (si && si->sin_addr.s_addr) {
    4134             :                         ssrc = si->sin_addr.s_addr;
    4135           0 :                         if (srcmask)
    4136           0 :                                 *srcmask = ntohl(sm->sin_addr.s_addr);
    4137             :                 }
    4138             : 
    4139           0 :                 si = (struct sockaddr_in *)ifa->ifa_dstaddr;
    4140           0 :                 if (si && si->sin_addr.s_addr)
    4141           0 :                         ddst = si->sin_addr.s_addr;
    4142             :         }
    4143             : 
    4144           0 :         if (dst) *dst = ntohl(ddst);
    4145           0 :         if (src) *src = ntohl(ssrc);
    4146           0 : }
    4147             : 
    4148             : int
    4149           0 : sppp_update_gw_walker(struct rtentry *rt, void *arg, unsigned int id)
    4150             : {
    4151           0 :         struct ifnet *ifp = arg;
    4152             : 
    4153           0 :         if (rt->rt_ifidx == ifp->if_index) {
    4154           0 :                 if (rt->rt_ifa->ifa_dstaddr->sa_family !=
    4155           0 :                     rt->rt_gateway->sa_family ||
    4156           0 :                     !ISSET(rt->rt_flags, RTF_GATEWAY))
    4157           0 :                         return (0);     /* do not modify non-gateway routes */
    4158           0 :                 rt_setgate(rt, rt->rt_ifa->ifa_dstaddr, ifp->if_rdomain);
    4159           0 :         }
    4160           0 :         return (0);
    4161           0 : }
    4162             : 
    4163             : void
    4164           0 : sppp_update_gw(struct ifnet *ifp)
    4165             : {
    4166             :         u_int tid;
    4167             : 
    4168             :         /* update routing table */
    4169           0 :         for (tid = 0; tid <= RT_TABLEID_MAX; tid++) {
    4170           0 :                 rtable_walk(tid, AF_INET, sppp_update_gw_walker, ifp);
    4171             :         }
    4172           0 : }
    4173             : 
    4174             : /*
    4175             :  * Task adding addresses from process context.
    4176             :  * If an address is 0, leave it the way it is.
    4177             :  */
    4178             : void
    4179           0 : sppp_set_ip_addrs(void *arg1)
    4180             : {
    4181           0 :         struct sppp *sp = arg1;
    4182           0 :         u_int32_t myaddr;
    4183           0 :         u_int32_t hisaddr;
    4184           0 :         struct ifnet *ifp = &sp->pp_if;
    4185           0 :         int debug = ifp->if_flags & IFF_DEBUG;
    4186             :         struct ifaddr *ifa;
    4187             :         struct sockaddr_in *si;
    4188             :         struct sockaddr_in *dest;
    4189             : 
    4190           0 :         sppp_get_ip_addrs(sp, &myaddr, &hisaddr, NULL);
    4191           0 :         if ((sp->ipcp.flags & IPCP_MYADDR_DYN) &&
    4192           0 :             (sp->ipcp.flags & IPCP_MYADDR_SEEN))
    4193           0 :                 myaddr = sp->ipcp.req_myaddr;
    4194           0 :         if ((sp->ipcp.flags & IPCP_HISADDR_DYN) &&
    4195           0 :             (sp->ipcp.flags & IPCP_HISADDR_SEEN))
    4196           0 :                 hisaddr = sp->ipcp.req_hisaddr;
    4197             : 
    4198             : 
    4199           0 :         NET_LOCK();
    4200             :         /*
    4201             :          * Pick the first AF_INET address from the list,
    4202             :          * aliases don't make any sense on a p2p link anyway.
    4203             :          */
    4204             : 
    4205             :         si = 0;
    4206           0 :         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
    4207             :         {
    4208           0 :                 if (ifa->ifa_addr->sa_family == AF_INET)
    4209             :                 {
    4210           0 :                         si = (struct sockaddr_in *)ifa->ifa_addr;
    4211           0 :                         dest = (struct sockaddr_in *)ifa->ifa_dstaddr;
    4212           0 :                         if (si)
    4213             :                                 break;
    4214             :                 }
    4215             :         }
    4216             : 
    4217           0 :         if (ifa && si) {
    4218             :                 int error;
    4219           0 :                 struct sockaddr_in new_sin = *si;
    4220           0 :                 struct sockaddr_in new_dst = *dest;
    4221             : 
    4222           0 :                 in_ifscrub(ifp, ifatoia(ifa));
    4223             : 
    4224           0 :                 if (myaddr != 0)
    4225           0 :                         new_sin.sin_addr.s_addr = htonl(myaddr);
    4226           0 :                 if (hisaddr != 0) {
    4227           0 :                         new_dst.sin_addr.s_addr = htonl(hisaddr);
    4228           0 :                         if (new_dst.sin_addr.s_addr != dest->sin_addr.s_addr) {
    4229           0 :                                 sp->ipcp.saved_hisaddr = dest->sin_addr.s_addr;
    4230           0 :                                 *dest = new_dst; /* fix dstaddr in place */
    4231           0 :                         }
    4232             :                 }
    4233           0 :                 if (!(error = in_ifinit(ifp, ifatoia(ifa), &new_sin, 0)))
    4234           0 :                         dohooks(ifp->if_addrhooks, 0);
    4235           0 :                 if (debug && error) {
    4236           0 :                         log(LOG_DEBUG, SPP_FMT "sppp_set_ip_addrs: in_ifinit "
    4237           0 :                         " failed, error=%d\n", SPP_ARGS(ifp), error);
    4238           0 :                         goto out;
    4239             :                 }
    4240           0 :                 sppp_update_gw(ifp);
    4241           0 :         }
    4242             : out:
    4243           0 :         NET_UNLOCK();
    4244           0 : }
    4245             : 
    4246             : /*
    4247             :  * Task clearing addresses from process context.
    4248             :  * Clear IP addresses.
    4249             :  */
    4250             : void
    4251           0 : sppp_clear_ip_addrs(void *arg1)
    4252             : {
    4253           0 :         struct sppp *sp = (struct sppp *)arg1;
    4254           0 :         struct ifnet *ifp = &sp->pp_if;
    4255           0 :         int debug = ifp->if_flags & IFF_DEBUG;
    4256             :         struct ifaddr *ifa;
    4257             :         struct sockaddr_in *si;
    4258             :         struct sockaddr_in *dest;
    4259           0 :         u_int32_t remote;
    4260             : 
    4261           0 :         NET_LOCK();
    4262             : 
    4263           0 :         if (sp->ipcp.flags & IPCP_HISADDR_DYN)
    4264           0 :                 remote = sp->ipcp.saved_hisaddr;
    4265             :         else
    4266           0 :                 sppp_get_ip_addrs(sp, 0, &remote, 0);
    4267             : 
    4268             :         /*
    4269             :          * Pick the first AF_INET address from the list,
    4270             :          * aliases don't make any sense on a p2p link anyway.
    4271             :          */
    4272             : 
    4273             :         si = 0;
    4274           0 :         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
    4275           0 :                 if (ifa->ifa_addr->sa_family == AF_INET) {
    4276           0 :                         si = (struct sockaddr_in *)ifa->ifa_addr;
    4277           0 :                         dest = (struct sockaddr_in *)ifa->ifa_dstaddr;
    4278           0 :                         if (si)
    4279             :                                 break;
    4280             :                 }
    4281             :         }
    4282             : 
    4283           0 :         if (ifa && si) {
    4284             :                 int error;
    4285           0 :                 struct sockaddr_in new_sin = *si;
    4286             : 
    4287           0 :                 in_ifscrub(ifp, ifatoia(ifa));
    4288           0 :                 if (sp->ipcp.flags & IPCP_MYADDR_DYN)
    4289           0 :                         new_sin.sin_addr.s_addr = 0;
    4290           0 :                 if (sp->ipcp.flags & IPCP_HISADDR_DYN)
    4291             :                         /* replace peer addr in place */
    4292           0 :                         dest->sin_addr.s_addr = sp->ipcp.saved_hisaddr;
    4293           0 :                 if (!(error = in_ifinit(ifp, ifatoia(ifa), &new_sin, 0)))
    4294           0 :                         dohooks(ifp->if_addrhooks, 0);
    4295           0 :                 if (debug && error) {
    4296           0 :                         log(LOG_DEBUG, SPP_FMT "sppp_clear_ip_addrs: in_ifinit "
    4297           0 :                         " failed, error=%d\n", SPP_ARGS(ifp), error);
    4298           0 :                         goto out;
    4299             :                 }
    4300           0 :                 sppp_update_gw(ifp);
    4301           0 :         }
    4302             : out:
    4303           0 :         NET_UNLOCK();
    4304           0 : }
    4305             : 
    4306             : 
    4307             : #ifdef INET6
    4308             : /*
    4309             :  * Get both IPv6 addresses.
    4310             :  */
    4311             : void
    4312           0 : sppp_get_ip6_addrs(struct sppp *sp, struct in6_addr *src, struct in6_addr *dst,
    4313             :                    struct in6_addr *srcmask)
    4314             : {
    4315           0 :         struct ifnet *ifp = &sp->pp_if;
    4316             :         struct in6_ifaddr *ia6;
    4317           0 :         struct in6_addr ssrc, ddst;
    4318             : 
    4319           0 :         bzero(&ssrc, sizeof(ssrc));
    4320           0 :         bzero(&ddst, sizeof(ddst));
    4321             :         /*
    4322             :          * Pick the first link-local AF_INET6 address from the list,
    4323             :          * aliases don't make any sense on a p2p link anyway.
    4324             :          */
    4325           0 :         ia6 = in6ifa_ifpforlinklocal(ifp, 0);
    4326           0 :         if (ia6) {
    4327           0 :                 if (!IN6_IS_ADDR_UNSPECIFIED(&ia6->ia_addr.sin6_addr)) {
    4328           0 :                         bcopy(&ia6->ia_addr.sin6_addr, &ssrc, sizeof(ssrc));
    4329           0 :                         if (srcmask) {
    4330           0 :                                 bcopy(&ia6->ia_prefixmask.sin6_addr, srcmask,
    4331             :                                     sizeof(*srcmask));
    4332           0 :                         }
    4333             :                 }
    4334             : 
    4335           0 :                 if (!IN6_IS_ADDR_UNSPECIFIED(&ia6->ia_dstaddr.sin6_addr))
    4336           0 :                         bcopy(&ia6->ia_dstaddr.sin6_addr, &ddst, sizeof(ddst));
    4337             :         }
    4338             : 
    4339           0 :         if (dst)
    4340           0 :                 bcopy(&ddst, dst, sizeof(*dst));
    4341           0 :         if (src)
    4342           0 :                 bcopy(&ssrc, src, sizeof(*src));
    4343           0 : }
    4344             : 
    4345             : /* Task to update my IPv6 address from process context. */
    4346             : void
    4347           0 : sppp_update_ip6_addr(void *arg)
    4348             : {
    4349           0 :         struct sppp *sp = arg;
    4350           0 :         struct ifnet *ifp = &sp->pp_if;
    4351           0 :         struct in6_aliasreq *ifra = &sp->ipv6cp.req_ifid;
    4352             :         struct in6_ifaddr *ia6;
    4353             :         int error;
    4354             : 
    4355           0 :         NET_LOCK();
    4356             : 
    4357           0 :         ia6 = in6ifa_ifpforlinklocal(ifp, 0);
    4358           0 :         if (ia6 == NULL) {
    4359             :                 /* IPv6 disabled? */
    4360             :                 goto out;
    4361             :         }
    4362             : 
    4363             :         /*
    4364             :          * Changing the link-local address requires purging all
    4365             :          * existing addresses and routes for the interface first.
    4366             :          */
    4367           0 :         if (sp->ipv6cp.flags & IPV6CP_MYIFID_DYN) {
    4368           0 :                 in6_ifdetach(ifp);
    4369           0 :                 error = in6_ifattach_linklocal(ifp, &ifra->ifra_addr.sin6_addr);
    4370           0 :                 if (error)
    4371           0 :                         log(LOG_ERR, SPP_FMT
    4372             :                             "could not update IPv6 address (error %d)\n",
    4373           0 :                             SPP_ARGS(ifp), error);
    4374             :                 goto out;
    4375             :         }
    4376             : 
    4377             :         /*
    4378             :          * Code below changes address parameters only, not the address itself.
    4379             :          */
    4380             : 
    4381             :         /* Destination address can only be set for /128. */
    4382           0 :         if (memcmp(&ia6->ia_prefixmask.sin6_addr, &in6mask128,
    4383           0 :             sizeof(in6mask128)) != 0) {
    4384           0 :                 ifra->ifra_dstaddr.sin6_len = 0;
    4385           0 :                 ifra->ifra_dstaddr.sin6_family = AF_UNSPEC;
    4386           0 :         }
    4387             : 
    4388           0 :         ifra->ifra_lifetime = ia6->ia6_lifetime;
    4389             : 
    4390           0 :         error = in6_update_ifa(ifp, ifra, ia6);
    4391           0 :         if (error) {
    4392           0 :                 log(LOG_ERR, SPP_FMT
    4393             :                     "could not update IPv6 address (error %d)\n",
    4394           0 :                     SPP_ARGS(ifp), error);
    4395           0 :         }
    4396             : out:
    4397           0 :         NET_UNLOCK();
    4398           0 : }
    4399             : 
    4400             : /*
    4401             :  * Configure my link-local address.
    4402             :  */
    4403             : void
    4404           0 : sppp_set_ip6_addr(struct sppp *sp, const struct in6_addr *src,
    4405             :         const struct in6_addr *dst)
    4406             : {
    4407           0 :         struct ifnet *ifp = &sp->pp_if;
    4408           0 :         struct in6_aliasreq *ifra = &sp->ipv6cp.req_ifid;
    4409             : 
    4410           0 :         bzero(ifra, sizeof(*ifra));
    4411           0 :         bcopy(ifp->if_xname, ifra->ifra_name, sizeof(ifra->ifra_name));
    4412             : 
    4413           0 :         ifra->ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
    4414           0 :         ifra->ifra_addr.sin6_family = AF_INET6;
    4415           0 :         ifra->ifra_addr.sin6_addr = *src;
    4416           0 :         if (dst) {
    4417           0 :                 ifra->ifra_dstaddr.sin6_len = sizeof(struct sockaddr_in6);
    4418           0 :                 ifra->ifra_dstaddr.sin6_family = AF_INET6;
    4419           0 :                 ifra->ifra_dstaddr.sin6_addr = *dst;
    4420           0 :         } else
    4421           0 :                 ifra->ifra_dstaddr.sin6_family = AF_UNSPEC;
    4422             : 
    4423             :         /*
    4424             :          * Don't change the existing prefixlen.
    4425             :          * It is common to use a /64 for IPv6 over point-to-point links
    4426             :          * to allow e.g. neighbour discovery and autoconf to work.
    4427             :          * But it is legal to use other values.
    4428             :          */
    4429           0 :         ifra->ifra_prefixmask.sin6_family = AF_UNSPEC;
    4430             : 
    4431           0 :         task_add(systq, &sp->ipv6cp.set_addr_task);
    4432           0 : }
    4433             : 
    4434             : /*
    4435             :  * Generate an address that differs from our existing address.
    4436             :  */
    4437             : void
    4438           0 : sppp_suggest_ip6_addr(struct sppp *sp, struct in6_addr *suggest)
    4439             : {
    4440           0 :         struct in6_addr myaddr;
    4441             :         u_int32_t random;
    4442             : 
    4443           0 :         sppp_get_ip6_addrs(sp, &myaddr, NULL, NULL);
    4444             : 
    4445           0 :         myaddr.s6_addr[8] &= ~0x02; /* u bit to "local" */
    4446             : 
    4447           0 :         random = arc4random();
    4448           0 :         if ((random & 0xff) == 0 && (random & 0xff00) == 0) {
    4449           0 :                 myaddr.s6_addr[14] ^= 0xff;
    4450           0 :                 myaddr.s6_addr[15] ^= 0xff;
    4451           0 :         } else {
    4452           0 :                 myaddr.s6_addr[14] ^= (random & 0xff);
    4453           0 :                 myaddr.s6_addr[15] ^= ((random & 0xff00) >> 8);
    4454             :         }
    4455           0 :         myaddr.s6_addr16[1] = 0; /* KAME hack: clear ifindex */
    4456           0 :         bcopy(&myaddr, suggest, sizeof(myaddr));
    4457           0 : }
    4458             : #endif /*INET6*/
    4459             : 
    4460             : int
    4461           0 : sppp_get_params(struct sppp *sp, struct ifreq *ifr)
    4462             : {
    4463           0 :         int cmd;
    4464             : 
    4465           0 :         if (copyin((caddr_t)ifr->ifr_data, &cmd, sizeof cmd) != 0)
    4466           0 :                 return EFAULT;
    4467             : 
    4468           0 :         switch (cmd) {
    4469             :         case SPPPIOGDEFS:
    4470             :         {
    4471             :                 struct spppreq *spr;
    4472             : 
    4473           0 :                 spr = malloc(sizeof(*spr), M_DEVBUF, M_WAITOK);
    4474           0 :                 spr->cmd = cmd;
    4475           0 :                 spr->phase = sp->pp_phase;
    4476             : 
    4477           0 :                 if (copyout(spr, (caddr_t)ifr->ifr_data, sizeof(*spr)) != 0) {
    4478             :                         free(spr, M_DEVBUF, 0);
    4479           0 :                         return EFAULT;
    4480             :                 }
    4481             :                 free(spr, M_DEVBUF, 0);
    4482           0 :                 break;
    4483             :         }
    4484             :         case SPPPIOGMAUTH:
    4485             :         case SPPPIOGHAUTH:
    4486             :         {
    4487             :                 struct sauthreq *spa;
    4488             :                 struct sauth *auth;
    4489             : 
    4490           0 :                 spa = malloc(sizeof(*spa), M_DEVBUF, M_WAITOK);
    4491           0 :                 auth = (cmd == SPPPIOGMAUTH) ? &sp->myauth : &sp->hisauth;
    4492           0 :                 bzero(spa, sizeof(*spa));
    4493           0 :                 spa->proto = auth->proto;
    4494           0 :                 spa->flags = auth->flags;
    4495             : 
    4496             :                 /* do not copy the secret, and only let root know the name */
    4497           0 :                 if (auth->name != NULL && suser(curproc) == 0)
    4498           0 :                         strlcpy(spa->name, auth->name, sizeof(spa->name));
    4499             : 
    4500           0 :                 if (copyout(spa, (caddr_t)ifr->ifr_data, sizeof(*spa)) != 0) {
    4501             :                         free(spa, M_DEVBUF, 0);
    4502           0 :                         return EFAULT;
    4503             :                 }
    4504             :                 free(spa, M_DEVBUF, 0);
    4505           0 :                 break;
    4506             :         }
    4507             :         default:
    4508           0 :                 return EINVAL;
    4509             :         }
    4510             : 
    4511           0 :         return 0;
    4512           0 : }
    4513             : 
    4514             : 
    4515             : int
    4516           0 : sppp_set_params(struct sppp *sp, struct ifreq *ifr)
    4517             : {
    4518           0 :         int cmd;
    4519             : 
    4520           0 :         if (copyin((caddr_t)ifr->ifr_data, &cmd, sizeof cmd) != 0)
    4521           0 :                 return EFAULT;
    4522             : 
    4523           0 :         switch (cmd) {
    4524             :         case SPPPIOSDEFS:
    4525             :         {
    4526             :                 struct spppreq *spr;
    4527             : 
    4528           0 :                 spr = malloc(sizeof(*spr), M_DEVBUF, M_WAITOK);
    4529             : 
    4530           0 :                 if (copyin((caddr_t)ifr->ifr_data, spr, sizeof(*spr)) != 0) {
    4531             :                         free(spr, M_DEVBUF, 0);
    4532           0 :                         return EFAULT;
    4533             :                 }
    4534             :                 /*
    4535             :                  * Also, we only allow for authentication parameters to be
    4536             :                  * specified.
    4537             :                  *
    4538             :                  * XXX Should allow to set or clear pp_flags.
    4539             :                  */
    4540             :                 free(spr, M_DEVBUF, 0);
    4541           0 :                 break;
    4542             :         }
    4543             :         case SPPPIOSMAUTH:
    4544             :         case SPPPIOSHAUTH:
    4545             :         {
    4546             :                 /*
    4547             :                  * Finally, if the respective authentication protocol to
    4548             :                  * be used is set differently than 0, but the secret is
    4549             :                  * passed as all zeros, we don't trash the existing secret.
    4550             :                  * This allows an administrator to change the system name
    4551             :                  * only without clobbering the secret (which he didn't get
    4552             :                  * back in a previous SPPPIOGXAUTH call).  However, the
    4553             :                  * secrets are cleared if the authentication protocol is
    4554             :                  * reset to 0.
    4555             :                  */
    4556             : 
    4557             :                 struct sauthreq *spa;
    4558             :                 struct sauth *auth;
    4559             :                 char *p;
    4560             :                 int len;
    4561             : 
    4562           0 :                 spa = malloc(sizeof(*spa), M_DEVBUF, M_WAITOK);
    4563             : 
    4564           0 :                 auth = (cmd == SPPPIOSMAUTH) ? &sp->myauth : &sp->hisauth;
    4565             : 
    4566           0 :                 if (copyin((caddr_t)ifr->ifr_data, spa, sizeof(*spa)) != 0) {
    4567           0 :                         free(spa, M_DEVBUF, 0);
    4568           0 :                         return EFAULT;
    4569             :                 }
    4570             : 
    4571           0 :                 if (spa->proto != 0 && spa->proto != PPP_PAP &&
    4572           0 :                     spa->proto != PPP_CHAP) {
    4573           0 :                         free(spa, M_DEVBUF, 0);
    4574           0 :                         return EINVAL;
    4575             :                 }
    4576             : 
    4577           0 :                 if (spa->proto == 0) {
    4578             :                         /* resetting auth */
    4579           0 :                         if (auth->name != NULL)
    4580           0 :                                 free(auth->name, M_DEVBUF, 0);
    4581           0 :                         if (auth->secret != NULL)
    4582           0 :                                 free(auth->secret, M_DEVBUF, 0);
    4583           0 :                         bzero(auth, sizeof *auth);
    4584           0 :                         explicit_bzero(sp->chap_challenge, sizeof sp->chap_challenge);
    4585           0 :                 } else {
    4586             :                         /* setting/changing auth */
    4587           0 :                         auth->proto = spa->proto;
    4588           0 :                         auth->flags = spa->flags;
    4589             : 
    4590           0 :                         spa->name[AUTHMAXLEN - 1] = '\0';
    4591           0 :                         len = strlen(spa->name) + 1;
    4592           0 :                         p = malloc(len, M_DEVBUF, M_WAITOK);
    4593           0 :                         strlcpy(p, spa->name, len);
    4594           0 :                         if (auth->name != NULL)
    4595           0 :                                 free(auth->name, M_DEVBUF, 0);
    4596           0 :                         auth->name = p;
    4597             : 
    4598           0 :                         if (spa->secret[0] != '\0') {
    4599           0 :                                 spa->secret[AUTHMAXLEN - 1] = '\0';
    4600           0 :                                 len = strlen(spa->secret) + 1;
    4601           0 :                                 p = malloc(len, M_DEVBUF, M_WAITOK);
    4602           0 :                                 strlcpy(p, spa->secret, len);
    4603           0 :                                 if (auth->secret != NULL)
    4604           0 :                                         free(auth->secret, M_DEVBUF, 0);
    4605           0 :                                 auth->secret = p;
    4606           0 :                         } else if (!auth->secret) {
    4607           0 :                                 p = malloc(1, M_DEVBUF, M_WAITOK);
    4608           0 :                                 p[0] = '\0';
    4609           0 :                                 auth->secret = p;
    4610           0 :                         }
    4611             :                 }
    4612           0 :                 free(spa, M_DEVBUF, 0);
    4613           0 :                 break;
    4614             :         }
    4615             :         default:
    4616           0 :                 return EINVAL;
    4617             :         }
    4618             : 
    4619           0 :         return (ENETRESET);
    4620           0 : }
    4621             : 
    4622             : void
    4623           0 : sppp_phase_network(struct sppp *sp)
    4624             : {
    4625             :         int i;
    4626             :         u_long mask;
    4627             : 
    4628           0 :         sp->pp_phase = PHASE_NETWORK;
    4629             : 
    4630           0 :         sppp_set_phase(sp);
    4631             : 
    4632             :         /* Notify NCPs now. */
    4633           0 :         for (i = 0; i < IDX_COUNT; i++)
    4634           0 :                 if ((cps[i])->flags & CP_NCP)
    4635           0 :                         (cps[i])->Open(sp);
    4636             : 
    4637             :         /* Send Up events to all NCPs. */
    4638           0 :         for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1)
    4639           0 :                 if (sp->lcp.protos & mask && ((cps[i])->flags & CP_NCP))
    4640           0 :                         (cps[i])->Up(sp);
    4641             : 
    4642             :         /* if no NCP is starting, all this was in vain, close down */
    4643           0 :         sppp_lcp_check_and_close(sp);
    4644           0 : }
    4645             : 
    4646             : 
    4647             : const char *
    4648           0 : sppp_cp_type_name(u_char type)
    4649             : {
    4650             :         static char buf[12];
    4651           0 :         switch (type) {
    4652           0 :         case CONF_REQ:   return "conf-req";
    4653           0 :         case CONF_ACK:   return "conf-ack";
    4654           0 :         case CONF_NAK:   return "conf-nak";
    4655           0 :         case CONF_REJ:   return "conf-rej";
    4656           0 :         case TERM_REQ:   return "term-req";
    4657           0 :         case TERM_ACK:   return "term-ack";
    4658           0 :         case CODE_REJ:   return "code-rej";
    4659           0 :         case PROTO_REJ:  return "proto-rej";
    4660           0 :         case ECHO_REQ:   return "echo-req";
    4661           0 :         case ECHO_REPLY: return "echo-reply";
    4662           0 :         case DISC_REQ:   return "discard-req";
    4663             :         }
    4664           0 :         snprintf (buf, sizeof buf, "0x%x", type);
    4665           0 :         return buf;
    4666           0 : }
    4667             : 
    4668             : const char *
    4669           0 : sppp_auth_type_name(u_short proto, u_char type)
    4670             : {
    4671             :         static char buf[12];
    4672           0 :         switch (proto) {
    4673             :         case PPP_CHAP:
    4674           0 :                 switch (type) {
    4675           0 :                 case CHAP_CHALLENGE:    return "challenge";
    4676           0 :                 case CHAP_RESPONSE:     return "response";
    4677           0 :                 case CHAP_SUCCESS:      return "success";
    4678           0 :                 case CHAP_FAILURE:      return "failure";
    4679             :                 }
    4680             :         case PPP_PAP:
    4681           0 :                 switch (type) {
    4682           0 :                 case PAP_REQ:           return "req";
    4683           0 :                 case PAP_ACK:           return "ack";
    4684           0 :                 case PAP_NAK:           return "nak";
    4685             :                 }
    4686             :         }
    4687           0 :         snprintf (buf, sizeof buf, "0x%x", type);
    4688           0 :         return buf;
    4689           0 : }
    4690             : 
    4691             : const char *
    4692           0 : sppp_lcp_opt_name(u_char opt)
    4693             : {
    4694             :         static char buf[12];
    4695           0 :         switch (opt) {
    4696           0 :         case LCP_OPT_MRU:               return "mru";
    4697           0 :         case LCP_OPT_ASYNC_MAP:         return "async-map";
    4698           0 :         case LCP_OPT_AUTH_PROTO:        return "auth-proto";
    4699           0 :         case LCP_OPT_QUAL_PROTO:        return "qual-proto";
    4700           0 :         case LCP_OPT_MAGIC:             return "magic";
    4701           0 :         case LCP_OPT_PROTO_COMP:        return "proto-comp";
    4702           0 :         case LCP_OPT_ADDR_COMP:         return "addr-comp";
    4703             :         }
    4704           0 :         snprintf (buf, sizeof buf, "0x%x", opt);
    4705           0 :         return buf;
    4706           0 : }
    4707             : 
    4708             : const char *
    4709           0 : sppp_ipcp_opt_name(u_char opt)
    4710             : {
    4711             :         static char buf[12];
    4712           0 :         switch (opt) {
    4713           0 :         case IPCP_OPT_ADDRESSES:        return "addresses";
    4714           0 :         case IPCP_OPT_COMPRESSION:      return "compression";
    4715           0 :         case IPCP_OPT_ADDRESS:          return "address";
    4716             :         }
    4717           0 :         snprintf (buf, sizeof buf, "0x%x", opt);
    4718           0 :         return buf;
    4719           0 : }
    4720             : 
    4721             : #ifdef INET6
    4722             : const char *
    4723           0 : sppp_ipv6cp_opt_name(u_char opt)
    4724             : {
    4725             :         static char buf[12];
    4726           0 :         switch (opt) {
    4727           0 :         case IPV6CP_OPT_IFID:           return "ifid";
    4728           0 :         case IPV6CP_OPT_COMPRESSION:    return "compression";
    4729             :         }
    4730           0 :         snprintf (buf, sizeof buf, "0x%x", opt);
    4731           0 :         return buf;
    4732           0 : }
    4733             : #endif
    4734             : 
    4735             : const char *
    4736           0 : sppp_state_name(int state)
    4737             : {
    4738           0 :         switch (state) {
    4739           0 :         case STATE_INITIAL:     return "initial";
    4740           0 :         case STATE_STARTING:    return "starting";
    4741           0 :         case STATE_CLOSED:      return "closed";
    4742           0 :         case STATE_STOPPED:     return "stopped";
    4743           0 :         case STATE_CLOSING:     return "closing";
    4744           0 :         case STATE_STOPPING:    return "stopping";
    4745           0 :         case STATE_REQ_SENT:    return "req-sent";
    4746           0 :         case STATE_ACK_RCVD:    return "ack-rcvd";
    4747           0 :         case STATE_ACK_SENT:    return "ack-sent";
    4748           0 :         case STATE_OPENED:      return "opened";
    4749             :         }
    4750           0 :         return "illegal";
    4751           0 : }
    4752             : 
    4753             : const char *
    4754           0 : sppp_phase_name(enum ppp_phase phase)
    4755             : {
    4756           0 :         switch (phase) {
    4757           0 :         case PHASE_DEAD:        return "dead";
    4758           0 :         case PHASE_ESTABLISH:   return "establish";
    4759           0 :         case PHASE_TERMINATE:   return "terminate";
    4760           0 :         case PHASE_AUTHENTICATE: return "authenticate";
    4761           0 :         case PHASE_NETWORK:     return "network";
    4762             :         }
    4763           0 :         return "illegal";
    4764           0 : }
    4765             : 
    4766             : const char *
    4767           0 : sppp_proto_name(u_short proto)
    4768             : {
    4769             :         static char buf[12];
    4770           0 :         switch (proto) {
    4771           0 :         case PPP_LCP:   return "lcp";
    4772           0 :         case PPP_IPCP:  return "ipcp";
    4773           0 :         case PPP_IPV6CP: return "ipv6cp";
    4774           0 :         case PPP_PAP:   return "pap";
    4775           0 :         case PPP_CHAP:  return "chap";
    4776             :         }
    4777           0 :         snprintf(buf, sizeof buf, "0x%x", (unsigned)proto);
    4778           0 :         return buf;
    4779           0 : }
    4780             : 
    4781             : void
    4782           0 : sppp_print_bytes(const u_char *p, u_short len)
    4783             : {
    4784           0 :         addlog(" %02x", *p++);
    4785           0 :         while (--len > 0)
    4786           0 :                 addlog("-%02x", *p++);
    4787           0 : }
    4788             : 
    4789             : void
    4790           0 : sppp_print_string(const char *p, u_short len)
    4791             : {
    4792             :         u_char c;
    4793             : 
    4794           0 :         while (len-- > 0) {
    4795           0 :                 c = *p++;
    4796             :                 /*
    4797             :                  * Print only ASCII chars directly.  RFC 1994 recommends
    4798             :                  * using only them, but we don't rely on it.  */
    4799           0 :                 if (c < ' ' || c > '~')
    4800           0 :                         addlog("\\x%x", c);
    4801             :                 else
    4802           0 :                         addlog("%c", c);
    4803             :         }
    4804           0 : }
    4805             : 
    4806             : const char *
    4807           0 : sppp_dotted_quad(u_int32_t addr)
    4808             : {
    4809             :         static char s[16];
    4810           0 :         snprintf(s, sizeof s, "%d.%d.%d.%d",
    4811           0 :                 (int)((addr >> 24) & 0xff),
    4812           0 :                 (int)((addr >> 16) & 0xff),
    4813           0 :                 (int)((addr >> 8) & 0xff),
    4814           0 :                 (int)(addr & 0xff));
    4815           0 :         return s;
    4816             : }
    4817             : 
    4818             : /* a dummy, used to drop uninteresting events */
    4819             : void
    4820           0 : sppp_null(struct sppp *unused)
    4821             : {
    4822             :         /* do just nothing */
    4823           0 : }
    4824             : 
    4825             : void
    4826           0 : sppp_set_phase(struct sppp *sp)
    4827             : {
    4828           0 :         STDDCL;
    4829             :         int lstate;
    4830             : 
    4831           0 :         if (debug)
    4832           0 :                 log(LOG_INFO, SPP_FMT "phase %s\n", SPP_ARGS(ifp),
    4833           0 :                     sppp_phase_name(sp->pp_phase));
    4834             : 
    4835             :         /* set link state */
    4836           0 :         if (sp->pp_phase == PHASE_NETWORK)
    4837           0 :                 lstate = LINK_STATE_UP;
    4838             :         else
    4839             :                 lstate = LINK_STATE_DOWN;
    4840             : 
    4841           0 :         if (ifp->if_link_state != lstate) {
    4842           0 :                 ifp->if_link_state = lstate;
    4843           0 :                 if_link_state_change(ifp);
    4844           0 :         }
    4845           0 : }

Generated by: LCOV version 1.13