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