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