[BACK]Return to if_spppsubr.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / net

Annotation of src/sys/net/if_spppsubr.c, Revision 1.66.2.6

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

CVSweb <webmaster@jp.NetBSD.org>