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