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