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