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