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