[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.44

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

CVSweb <webmaster@jp.NetBSD.org>