[BACK]Return to if_spppsubr.c CVS log [TXT][DIR] Up to [local] / sys / net

Annotation of sys/net/if_spppsubr.c, Revision 1.1

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

CVSweb