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