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

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

CVSweb <webmaster@jp.NetBSD.org>