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

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

CVSweb <webmaster@jp.NetBSD.org>