if_spppsubr.c revision 35029
1203955Srdivacky/* 2203955Srdivacky * Synchronous PPP/Cisco link level subroutines. 3203955Srdivacky * Keepalive protocol implemented in both Cisco and PPP modes. 4203955Srdivacky * 5203955Srdivacky * Copyright (C) 1994-1996 Cronyx Engineering Ltd. 6203955Srdivacky * Author: Serge Vakulenko, <vak@cronyx.ru> 7203955Srdivacky * 8203955Srdivacky * Heavily revamped to conform to RFC 1661. 9203955Srdivacky * Copyright (C) 1997, Joerg Wunsch. 10203955Srdivacky * 11203955Srdivacky * This software is distributed with NO WARRANTIES, not even the implied 12203955Srdivacky * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13203955Srdivacky * 14203955Srdivacky * Authors grant any other persons or organisations permission to use 15203955Srdivacky * or modify this software as long as this message is kept with the software, 16249423Sdim * all derivative works or modified versions. 17249423Sdim * 18239462Sdim * From: Version 2.4, Thu Apr 30 17:17:21 MSD 1997 19203955Srdivacky * 20239462Sdim * $Id: if_spppsubr.c,v 1.35 1998/03/30 09:52:06 phk Exp $ 21203955Srdivacky */ 22203955Srdivacky 23203955Srdivacky#include "opt_inet.h" 24203955Srdivacky#include "opt_ipx.h" 25208600Srdivacky 26208600Srdivacky#include <sys/param.h> 27208600Srdivacky#include <sys/systm.h> 28208600Srdivacky#include <sys/kernel.h> 29208600Srdivacky#include <sys/sockio.h> 30203955Srdivacky#include <sys/socket.h> 31208600Srdivacky#include <sys/syslog.h> 32208600Srdivacky#include <machine/random.h> 33203955Srdivacky#include <sys/malloc.h> 34218893Sdim#include <sys/mbuf.h> 35218893Sdim#include <sys/md5.h> 36203955Srdivacky 37203955Srdivacky#include <net/if.h> 38218893Sdim#include <net/netisr.h> 39218893Sdim#include <net/if_types.h> 40218893Sdim 41203955Srdivacky#include <machine/stdarg.h> 42203955Srdivacky 43218893Sdim#ifdef INET 44218893Sdim#include <netinet/in.h> 45218893Sdim#include <netinet/in_systm.h> 46218893Sdim#include <netinet/in_var.h> 47218893Sdim#include <netinet/ip.h> 48218893Sdim#include <netinet/tcp.h> 49221345Sdim#include <netinet/if_ether.h> 50221345Sdim#else 51221345Sdim#error Huh? sppp without INET? 52221345Sdim#endif 53221345Sdim 54218893Sdim#ifdef IPX 55218893Sdim#include <netipx/ipx.h> 56218893Sdim#include <netipx/ipx_if.h> 57218893Sdim#endif 58218893Sdim 59218893Sdim#ifdef NS 60218893Sdim#include <netns/ns.h> 61208600Srdivacky#include <netns/ns_if.h> 62223017Sdim#endif 63223017Sdim 64223017Sdim#ifdef ISO 65223017Sdim#include <netiso/argo_debug.h> 66223017Sdim#include <netiso/iso.h> 67208600Srdivacky#include <netiso/iso_var.h> 68203955Srdivacky#include <netiso/iso_snpac.h> 69203955Srdivacky#endif 70203955Srdivacky 71203955Srdivacky#include <net/if_sppp.h> 72203955Srdivacky 73203955Srdivacky#define MAXALIVECNT 3 /* max. alive packets */ 74208600Srdivacky 75203955Srdivacky/* 76203955Srdivacky * Interface flags that can be set in an ifconfig command. 77203955Srdivacky * 78208600Srdivacky * Setting link0 will make the link passive, i.e. it will be marked 79203955Srdivacky * as being administrative openable, but won't be opened to begin 80203955Srdivacky * with. Incoming calls will be answered, or subsequent calls with 81203955Srdivacky * -link1 will cause the administrative open of the LCP layer. 82203955Srdivacky * 83203955Srdivacky * Setting link1 will cause the link to auto-dial only as packets 84203955Srdivacky * arrive to be sent. 85203955Srdivacky * 86203955Srdivacky * Setting IFF_DEBUG will syslog the option negotiation and state 87203955Srdivacky * transitions at level kern.debug. Note: all logs consistently look 88203955Srdivacky * like 89203955Srdivacky * 90203955Srdivacky * <if-name><unit>: <proto-name> <additional info...> 91203955Srdivacky * 92203955Srdivacky * with <if-name><unit> being something like "bppp0", and <proto-name> 93203955Srdivacky * being one of "lcp", "ipcp", "cisco", "chap", "pap", etc. 94203955Srdivacky */ 95208600Srdivacky 96203955Srdivacky#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ 97203955Srdivacky#define IFF_AUTO IFF_LINK1 /* auto-dial on output */ 98203955Srdivacky 99208600Srdivacky#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ 100203955Srdivacky#define PPP_UI 0x03 /* Unnumbered Information */ 101203955Srdivacky#define PPP_IP 0x0021 /* Internet Protocol */ 102203955Srdivacky#define PPP_ISO 0x0023 /* ISO OSI Protocol */ 103203955Srdivacky#define PPP_XNS 0x0025 /* Xerox NS Protocol */ 104208600Srdivacky#define PPP_IPX 0x002b /* Novell IPX Protocol */ 105203955Srdivacky#define PPP_LCP 0xc021 /* Link Control Protocol */ 106218893Sdim#define PPP_PAP 0xc023 /* Password Authentication Protocol */ 107218893Sdim#define PPP_CHAP 0xc223 /* Challenge-Handshake Auth Protocol */ 108221345Sdim#define PPP_IPCP 0x8021 /* Internet Protocol Control Protocol */ 109218893Sdim 110208600Srdivacky#define CONF_REQ 1 /* PPP configure request */ 111208600Srdivacky#define CONF_ACK 2 /* PPP configure acknowledge */ 112208600Srdivacky#define CONF_NAK 3 /* PPP configure negative ack */ 113203955Srdivacky#define CONF_REJ 4 /* PPP configure reject */ 114203955Srdivacky#define TERM_REQ 5 /* PPP terminate request */ 115208600Srdivacky#define TERM_ACK 6 /* PPP terminate acknowledge */ 116208600Srdivacky#define CODE_REJ 7 /* PPP code reject */ 117208600Srdivacky#define PROTO_REJ 8 /* PPP protocol reject */ 118208600Srdivacky#define ECHO_REQ 9 /* PPP echo request */ 119218893Sdim#define ECHO_REPLY 10 /* PPP echo reply */ 120218893Sdim#define DISC_REQ 11 /* PPP discard request */ 121208600Srdivacky 122218893Sdim#define LCP_OPT_MRU 1 /* maximum receive unit */ 123218893Sdim#define LCP_OPT_ASYNC_MAP 2 /* async control character map */ 124218893Sdim#define LCP_OPT_AUTH_PROTO 3 /* authentication protocol */ 125218893Sdim#define LCP_OPT_QUAL_PROTO 4 /* quality protocol */ 126218893Sdim#define LCP_OPT_MAGIC 5 /* magic number */ 127203955Srdivacky#define LCP_OPT_RESERVED 6 /* reserved */ 128208600Srdivacky#define LCP_OPT_PROTO_COMP 7 /* protocol field compression */ 129218893Sdim#define LCP_OPT_ADDR_COMP 8 /* address/control field compression */ 130203955Srdivacky 131203955Srdivacky#define IPCP_OPT_ADDRESSES 1 /* both IP addresses; deprecated */ 132203955Srdivacky#define IPCP_OPT_COMPRESSION 2 /* IP compression protocol (VJ) */ 133208600Srdivacky#define IPCP_OPT_ADDRESS 3 /* local IP address */ 134203955Srdivacky 135224145Sdim#define PAP_REQ 1 /* PAP name/password request */ 136208600Srdivacky#define PAP_ACK 2 /* PAP acknowledge */ 137208600Srdivacky#define PAP_NAK 3 /* PAP fail */ 138208600Srdivacky 139208600Srdivacky#define CHAP_CHALLENGE 1 /* CHAP challenge request */ 140208600Srdivacky#define CHAP_RESPONSE 2 /* CHAP challenge response */ 141208600Srdivacky#define CHAP_SUCCESS 3 /* CHAP response ok */ 142208600Srdivacky#define CHAP_FAILURE 4 /* CHAP response failed */ 143208600Srdivacky 144208600Srdivacky#define CHAP_MD5 5 /* hash algorithm - MD5 */ 145208600Srdivacky 146208600Srdivacky#define CISCO_MULTICAST 0x8f /* Cisco multicast address */ 147208600Srdivacky#define CISCO_UNICAST 0x0f /* Cisco unicast address */ 148224145Sdim#define CISCO_KEEPALIVE 0x8035 /* Cisco keepalive protocol */ 149224145Sdim#define CISCO_ADDR_REQ 0 /* Cisco address request */ 150224145Sdim#define CISCO_ADDR_REPLY 1 /* Cisco address reply */ 151208600Srdivacky#define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */ 152203955Srdivacky 153203955Srdivacky/* states are named and numbered according to RFC 1661 */ 154224145Sdim#define STATE_INITIAL 0 155224145Sdim#define STATE_STARTING 1 156203955Srdivacky#define STATE_CLOSED 2 157203955Srdivacky#define STATE_STOPPED 3 158226633Sdim#define STATE_CLOSING 4 159224145Sdim#define STATE_STOPPING 5 160234353Sdim#define STATE_REQ_SENT 6 161203955Srdivacky#define STATE_ACK_RCVD 7 162224145Sdim#define STATE_ACK_SENT 8 163224145Sdim#define STATE_OPENED 9 164226633Sdim 165226633Sdimstruct ppp_header { 166208600Srdivacky u_char address; 167234353Sdim u_char control; 168224145Sdim u_short protocol; 169234353Sdim}; 170234353Sdim#define PPP_HEADER_LEN sizeof (struct ppp_header) 171234353Sdim 172224145Sdimstruct lcp_header { 173224145Sdim u_char type; 174224145Sdim u_char ident; 175224145Sdim u_short len; 176224145Sdim}; 177226633Sdim#define LCP_HEADER_LEN sizeof (struct lcp_header) 178234353Sdim 179234353Sdimstruct cisco_packet { 180234353Sdim u_long type; 181234353Sdim u_long par1; 182234353Sdim u_long par2; 183234353Sdim u_short rel; 184234353Sdim u_short time0; 185234353Sdim u_short time1; 186234353Sdim}; 187234353Sdim#define CISCO_PACKET_LEN 18 188224145Sdim 189224145Sdim/* 190224145Sdim * We follow the spelling and capitalization of RFC 1661 here, to make 191224145Sdim * it easier comparing with the standard. Please refer to this RFC in 192224145Sdim * case you can't make sense out of these abbreviation; it will also 193224145Sdim * explain the semantics related to the various events and actions. 194224145Sdim */ 195208600Srdivackystruct cp { 196208600Srdivacky u_short proto; /* PPP control protocol number */ 197208600Srdivacky u_char protoidx; /* index into state table in struct sppp */ 198208600Srdivacky u_char flags; 199208600Srdivacky#define CP_LCP 0x01 /* this is the LCP */ 200226633Sdim#define CP_AUTH 0x02 /* this is an authentication protocol */ 201208600Srdivacky#define CP_NCP 0x04 /* this is a NCP */ 202208600Srdivacky#define CP_QUAL 0x08 /* this is a quality reporting protocol */ 203208600Srdivacky const char *name; /* name of this control protocol */ 204208600Srdivacky /* event handlers */ 205208600Srdivacky void (*Up)(struct sppp *sp); 206208600Srdivacky void (*Down)(struct sppp *sp); 207208600Srdivacky void (*Open)(struct sppp *sp); 208208600Srdivacky void (*Close)(struct sppp *sp); 209208600Srdivacky void (*TO)(void *sp); 210203955Srdivacky int (*RCR)(struct sppp *sp, struct lcp_header *h, int len); 211203955Srdivacky void (*RCN_rej)(struct sppp *sp, struct lcp_header *h, int len); 212208600Srdivacky void (*RCN_nak)(struct sppp *sp, struct lcp_header *h, int len); 213208600Srdivacky /* actions */ 214208600Srdivacky void (*tlu)(struct sppp *sp); 215224145Sdim void (*tld)(struct sppp *sp); 216224145Sdim void (*tls)(struct sppp *sp); 217224145Sdim void (*tlf)(struct sppp *sp); 218224145Sdim void (*scr)(struct sppp *sp); 219226633Sdim}; 220224145Sdim 221224145Sdimstatic struct sppp *spppq; 222224145Sdimstatic struct callout_handle keepalive_ch; 223224145Sdim 224208600Srdivacky/* 225203955Srdivacky * The following disgusting hack gets around the problem that IP TOS 226208600Srdivacky * can't be set yet. We want to put "interactive" traffic on a high 227203955Srdivacky * priority queue. To decide if traffic is interactive, we check that 228203955Srdivacky * a) it is TCP and b) one of its ports is telnet, rlogin or ftp control. 229203955Srdivacky * 230203955Srdivacky * XXX is this really still necessary? - joerg - 231239462Sdim */ 232239462Sdimstatic u_short interactive_ports[8] = { 233239462Sdim 0, 513, 0, 0, 234249423Sdim 0, 21, 0, 23, 235239462Sdim}; 236224145Sdim#define INTERACTIVE(p) (interactive_ports[(p) & 7] == (p)) 237226633Sdim 238224145Sdim/* almost every function needs these */ 239224145Sdim#define STDDCL \ 240224145Sdim struct ifnet *ifp = &sp->pp_if; \ 241224145Sdim int debug = ifp->if_flags & IFF_DEBUG 242224145Sdim 243226633Sdimstatic int sppp_output(struct ifnet *ifp, struct mbuf *m, 244224145Sdim struct sockaddr *dst, struct rtentry *rt); 245226633Sdim 246224145Sdimstatic void sppp_cisco_send(struct sppp *sp, int type, long par1, long par2); 247234353Sdimstatic void sppp_cisco_input(struct sppp *sp, struct mbuf *m); 248203955Srdivacky 249203955Srdivackystatic void sppp_cp_input(const struct cp *cp, struct sppp *sp, 250249423Sdim struct mbuf *m); 251249423Sdimstatic void sppp_cp_send(struct sppp *sp, u_short proto, u_char type, 252203955Srdivacky u_char ident, u_short len, void *data); 253203955Srdivackystatic void sppp_cp_timeout(void *arg); 254203955Srdivackystatic void sppp_cp_change_state(const struct cp *cp, struct sppp *sp, 255226633Sdim int newstate); 256239462Sdimstatic void sppp_auth_send(const struct cp *cp, 257239462Sdim struct sppp *sp, u_char type, u_char id, 258239462Sdim ...); 259239462Sdim 260239462Sdimstatic void sppp_up_event(const struct cp *cp, struct sppp *sp); 261239462Sdimstatic void sppp_down_event(const struct cp *cp, struct sppp *sp); 262239462Sdimstatic void sppp_open_event(const struct cp *cp, struct sppp *sp); 263239462Sdimstatic void sppp_close_event(const struct cp *cp, struct sppp *sp); 264239462Sdimstatic void sppp_to_event(const struct cp *cp, struct sppp *sp); 265249423Sdim 266239462Sdimstatic void sppp_null(struct sppp *sp); 267239462Sdim 268239462Sdimstatic void sppp_lcp_init(struct sppp *sp); 269239462Sdimstatic void sppp_lcp_up(struct sppp *sp); 270239462Sdimstatic void sppp_lcp_down(struct sppp *sp); 271239462Sdimstatic void sppp_lcp_open(struct sppp *sp); 272239462Sdimstatic void sppp_lcp_close(struct sppp *sp); 273239462Sdimstatic void sppp_lcp_TO(void *sp); 274239462Sdimstatic int sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len); 275239462Sdimstatic void sppp_lcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len); 276249423Sdimstatic void sppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len); 277239462Sdimstatic void sppp_lcp_tlu(struct sppp *sp); 278239462Sdimstatic void sppp_lcp_tld(struct sppp *sp); 279239462Sdimstatic void sppp_lcp_tls(struct sppp *sp); 280239462Sdimstatic void sppp_lcp_tlf(struct sppp *sp); 281239462Sdimstatic void sppp_lcp_scr(struct sppp *sp); 282239462Sdimstatic void sppp_lcp_check_and_close(struct sppp *sp); 283226633Sdimstatic int sppp_ncp_check(struct sppp *sp); 284203955Srdivacky 285203955Srdivackystatic void sppp_ipcp_init(struct sppp *sp); 286203955Srdivackystatic void sppp_ipcp_up(struct sppp *sp); 287203955Srdivackystatic void sppp_ipcp_down(struct sppp *sp); 288249423Sdimstatic void sppp_ipcp_open(struct sppp *sp); 289249423Sdimstatic void sppp_ipcp_close(struct sppp *sp); 290203955Srdivackystatic void sppp_ipcp_TO(void *sp); 291203955Srdivackystatic int sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len); 292203955Srdivackystatic void sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len); 293226633Sdimstatic void sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len); 294203955Srdivackystatic void sppp_ipcp_tlu(struct sppp *sp); 295249423Sdimstatic void sppp_ipcp_tld(struct sppp *sp); 296203955Srdivackystatic void sppp_ipcp_tls(struct sppp *sp); 297203955Srdivackystatic void sppp_ipcp_tlf(struct sppp *sp); 298249423Sdimstatic void sppp_ipcp_scr(struct sppp *sp); 299203955Srdivacky 300203955Srdivackystatic void sppp_pap_input(struct sppp *sp, struct mbuf *m); 301203955Srdivackystatic void sppp_pap_init(struct sppp *sp); 302249423Sdimstatic void sppp_pap_open(struct sppp *sp); 303263508Sdimstatic void sppp_pap_close(struct sppp *sp); 304203955Srdivackystatic void sppp_pap_TO(void *sp); 305203955Srdivackystatic void sppp_pap_my_TO(void *sp); 306226633Sdimstatic void sppp_pap_tlu(struct sppp *sp); 307203955Srdivackystatic void sppp_pap_tld(struct sppp *sp); 308203955Srdivackystatic void sppp_pap_scr(struct sppp *sp); 309203955Srdivacky 310203955Srdivackystatic void sppp_chap_input(struct sppp *sp, struct mbuf *m); 311203955Srdivackystatic void sppp_chap_init(struct sppp *sp); 312203955Srdivackystatic void sppp_chap_open(struct sppp *sp); 313203955Srdivackystatic void sppp_chap_close(struct sppp *sp); 314203955Srdivackystatic void sppp_chap_TO(void *sp); 315226633Sdimstatic void sppp_chap_tlu(struct sppp *sp); 316249423Sdimstatic void sppp_chap_tld(struct sppp *sp); 317203955Srdivackystatic void sppp_chap_scr(struct sppp *sp); 318203955Srdivacky 319226633Sdimstatic const char *sppp_auth_type_name(u_short proto, u_char type); 320249423Sdimstatic const char *sppp_cp_type_name(u_char type); 321249423Sdimstatic const char *sppp_dotted_quad(u_long addr); 322203955Srdivackystatic const char *sppp_ipcp_opt_name(u_char opt); 323203955Srdivackystatic const char *sppp_lcp_opt_name(u_char opt); 324203955Srdivackystatic const char *sppp_phase_name(enum ppp_phase phase); 325226633Sdimstatic const char *sppp_proto_name(u_short proto); 326203955Srdivackystatic const char *sppp_state_name(int state); 327203955Srdivackystatic int sppp_params(struct sppp *sp, int cmd, void *data); 328203955Srdivackystatic int sppp_strnlen(u_char *p, int max); 329203955Srdivackystatic void sppp_get_ip_addrs(struct sppp *sp, u_long *src, u_long *dst, 330203955Srdivacky u_long *srcmask); 331234353Sdimstatic void sppp_keepalive(void *dummy); 332249423Sdimstatic void sppp_phase_network(struct sppp *sp); 333203955Srdivackystatic void sppp_print_bytes(const u_char *p, u_short len); 334249423Sdimstatic void sppp_print_string(const char *p, u_short len); 335203955Srdivackystatic void sppp_qflush(struct ifqueue *ifq); 336249423Sdimstatic void sppp_set_ip_addr(struct sppp *sp, u_long src); 337249423Sdim 338249423Sdim/* our control protocol descriptors */ 339249423Sdimstatic const struct cp lcp = { 340203955Srdivacky PPP_LCP, IDX_LCP, CP_LCP, "lcp", 341203955Srdivacky sppp_lcp_up, sppp_lcp_down, sppp_lcp_open, sppp_lcp_close, 342203955Srdivacky sppp_lcp_TO, sppp_lcp_RCR, sppp_lcp_RCN_rej, sppp_lcp_RCN_nak, 343203955Srdivacky sppp_lcp_tlu, sppp_lcp_tld, sppp_lcp_tls, sppp_lcp_tlf, 344249423Sdim sppp_lcp_scr 345203955Srdivacky}; 346249423Sdim 347203955Srdivackystatic const struct cp ipcp = { 348249423Sdim PPP_IPCP, IDX_IPCP, CP_NCP, "ipcp", 349249423Sdim sppp_ipcp_up, sppp_ipcp_down, sppp_ipcp_open, sppp_ipcp_close, 350249423Sdim sppp_ipcp_TO, sppp_ipcp_RCR, sppp_ipcp_RCN_rej, sppp_ipcp_RCN_nak, 351249423Sdim sppp_ipcp_tlu, sppp_ipcp_tld, sppp_ipcp_tls, sppp_ipcp_tlf, 352249423Sdim sppp_ipcp_scr 353203955Srdivacky}; 354203955Srdivacky 355203955Srdivackystatic const struct cp pap = { 356203955Srdivacky PPP_PAP, IDX_PAP, CP_AUTH, "pap", 357203955Srdivacky sppp_null, sppp_null, sppp_pap_open, sppp_pap_close, 358249423Sdim sppp_pap_TO, 0, 0, 0, 359249423Sdim sppp_pap_tlu, sppp_pap_tld, sppp_null, sppp_null, 360249423Sdim sppp_pap_scr 361249423Sdim}; 362249423Sdim 363203955Srdivackystatic const struct cp chap = { 364249423Sdim PPP_CHAP, IDX_CHAP, CP_AUTH, "chap", 365203955Srdivacky sppp_null, sppp_null, sppp_chap_open, sppp_chap_close, 366239462Sdim sppp_chap_TO, 0, 0, 0, 367239462Sdim sppp_chap_tlu, sppp_chap_tld, sppp_null, sppp_null, 368239462Sdim sppp_chap_scr 369239462Sdim}; 370239462Sdim 371239462Sdimstatic const struct cp *cps[IDX_COUNT] = { 372239462Sdim &lcp, /* IDX_LCP */ 373239462Sdim &ipcp, /* IDX_IPCP */ 374239462Sdim &pap, /* IDX_PAP */ 375239462Sdim &chap, /* IDX_CHAP */ 376239462Sdim}; 377239462Sdim 378239462Sdim 379239462Sdim/* 380239462Sdim * Exported functions, comprising our interface to the lower layer. 381239462Sdim */ 382239462Sdim 383239462Sdim/* 384239462Sdim * Process the received packet. 385239462Sdim */ 386239462Sdimvoid 387239462Sdimsppp_input(struct ifnet *ifp, struct mbuf *m) 388239462Sdim{ 389239462Sdim struct ppp_header *h; 390239462Sdim struct ifqueue *inq = 0; 391239462Sdim int s; 392239462Sdim struct sppp *sp = (struct sppp *)ifp; 393239462Sdim int debug = ifp->if_flags & IFF_DEBUG; 394239462Sdim 395239462Sdim if (ifp->if_flags & IFF_UP) 396239462Sdim /* Count received bytes, add FCS and one flag */ 397239462Sdim ifp->if_ibytes += m->m_pkthdr.len + 3; 398249423Sdim 399239462Sdim if (m->m_pkthdr.len <= PPP_HEADER_LEN) { 400239462Sdim /* Too small packet, drop it. */ 401239462Sdim if (debug) 402239462Sdim log(LOG_DEBUG, 403239462Sdim "%s%d: input packet is too small, %d bytes\n", 404239462Sdim ifp->if_name, ifp->if_unit, m->m_pkthdr.len); 405249423Sdim drop: 406249423Sdim ++ifp->if_ierrors; 407249423Sdim ++ifp->if_iqdrops; 408249423Sdim m_freem (m); 409249423Sdim return; 410249423Sdim } 411249423Sdim 412249423Sdim /* Get PPP header. */ 413249423Sdim h = mtod (m, struct ppp_header*); 414249423Sdim m_adj (m, PPP_HEADER_LEN); 415249423Sdim 416249423Sdim switch (h->address) { 417249423Sdim case PPP_ALLSTATIONS: 418249423Sdim if (h->control != PPP_UI) 419249423Sdim goto invalid; 420249423Sdim if (sp->pp_flags & PP_CISCO) { 421249423Sdim if (debug) 422249423Sdim log(LOG_DEBUG, 423249423Sdim "%s%d: PPP packet in Cisco mode " 424239462Sdim "<addr=0x%x ctrl=0x%x proto=0x%x>\n", 425239462Sdim ifp->if_name, ifp->if_unit, 426239462Sdim h->address, h->control, ntohs(h->protocol)); 427239462Sdim goto drop; 428249423Sdim } 429249423Sdim switch (ntohs (h->protocol)) { 430239462Sdim default: 431239462Sdim if (sp->state[IDX_LCP] == STATE_OPENED) 432239462Sdim sppp_cp_send (sp, PPP_LCP, PROTO_REJ, 433239462Sdim ++sp->pp_seq, m->m_pkthdr.len + 2, 434239462Sdim &h->protocol); 435239462Sdim if (debug) 436239462Sdim log(LOG_DEBUG, 437239462Sdim "%s%d: invalid input protocol " 438239462Sdim "<addr=0x%x ctrl=0x%x proto=0x%x>\n", 439239462Sdim ifp->if_name, ifp->if_unit, 440239462Sdim h->address, h->control, ntohs(h->protocol)); 441239462Sdim ++ifp->if_noproto; 442239462Sdim goto drop; 443239462Sdim case PPP_LCP: 444239462Sdim sppp_cp_input(&lcp, sp, m); 445239462Sdim m_freem (m); 446239462Sdim return; 447239462Sdim case PPP_PAP: 448239462Sdim if (sp->pp_phase >= PHASE_AUTHENTICATE) 449243830Sdim sppp_pap_input(sp, m); 450243830Sdim m_freem (m); 451243830Sdim return; 452243830Sdim case PPP_CHAP: 453243830Sdim if (sp->pp_phase >= PHASE_AUTHENTICATE) 454243830Sdim sppp_chap_input(sp, m); 455243830Sdim m_freem (m); 456243830Sdim return; 457243830Sdim#ifdef INET 458249423Sdim case PPP_IPCP: 459249423Sdim if (sp->pp_phase == PHASE_NETWORK) 460249423Sdim sppp_cp_input(&ipcp, sp, m); 461263508Sdim m_freem (m); 462263508Sdim return; 463263508Sdim case PPP_IP: 464263508Sdim if (sp->state[IDX_IPCP] == STATE_OPENED) { 465239462Sdim schednetisr (NETISR_IP); 466239462Sdim inq = &ipintrq; 467239462Sdim } 468239462Sdim break; 469239462Sdim#endif 470239462Sdim#ifdef IPX 471239462Sdim case PPP_IPX: 472249423Sdim /* IPX IPXCP not implemented yet */ 473239462Sdim if (sp->pp_phase == PHASE_NETWORK) { 474249423Sdim schednetisr (NETISR_IPX); 475263508Sdim inq = &ipxintrq; 476263508Sdim } 477239462Sdim break; 478239462Sdim#endif 479239462Sdim#ifdef NS 480249423Sdim case PPP_XNS: 481239462Sdim /* XNS IDPCP not implemented yet */ 482239462Sdim if (sp->pp_phase == PHASE_NETWORK) { 483239462Sdim schednetisr (NETISR_NS); 484239462Sdim inq = &nsintrq; 485239462Sdim } 486239462Sdim break; 487239462Sdim#endif 488239462Sdim#ifdef ISO 489239462Sdim case PPP_ISO: 490239462Sdim /* OSI NLCP not implemented yet */ 491239462Sdim if (sp->pp_phase == PHASE_NETWORK) { 492239462Sdim schednetisr (NETISR_ISO); 493239462Sdim inq = &clnlintrq; 494239462Sdim } 495239462Sdim break; 496239462Sdim#endif 497239462Sdim } 498239462Sdim break; 499239462Sdim case CISCO_MULTICAST: 500239462Sdim case CISCO_UNICAST: 501239462Sdim /* Don't check the control field here (RFC 1547). */ 502239462Sdim if (! (sp->pp_flags & PP_CISCO)) { 503239462Sdim if (debug) 504239462Sdim log(LOG_DEBUG, 505239462Sdim "%s%d: Cisco packet in PPP mode " 506239462Sdim "<addr=0x%x ctrl=0x%x proto=0x%x>\n", 507239462Sdim ifp->if_name, ifp->if_unit, 508239462Sdim h->address, h->control, ntohs(h->protocol)); 509239462Sdim goto drop; 510239462Sdim } 511239462Sdim switch (ntohs (h->protocol)) { 512239462Sdim default: 513239462Sdim ++ifp->if_noproto; 514239462Sdim goto invalid; 515239462Sdim case CISCO_KEEPALIVE: 516239462Sdim sppp_cisco_input ((struct sppp*) ifp, m); 517243830Sdim m_freem (m); 518243830Sdim return; 519243830Sdim#ifdef INET 520243830Sdim case ETHERTYPE_IP: 521243830Sdim schednetisr (NETISR_IP); 522243830Sdim inq = &ipintrq; 523243830Sdim break; 524243830Sdim#endif 525243830Sdim#ifdef IPX 526243830Sdim case ETHERTYPE_IPX: 527243830Sdim schednetisr (NETISR_IPX); 528243830Sdim inq = &ipxintrq; 529243830Sdim break; 530243830Sdim#endif 531243830Sdim#ifdef NS 532249423Sdim case ETHERTYPE_NS: 533263508Sdim schednetisr (NETISR_NS); 534263508Sdim inq = &nsintrq; 535249423Sdim break; 536249423Sdim#endif 537263508Sdim } 538263508Sdim break; 539249423Sdim default: /* Invalid PPP packet. */ 540249423Sdim invalid: 541239462Sdim if (debug) 542239462Sdim log(LOG_DEBUG, 543239462Sdim "%s%d: invalid input packet " 544239462Sdim "<addr=0x%x ctrl=0x%x proto=0x%x>\n", 545239462Sdim ifp->if_name, ifp->if_unit, 546239462Sdim h->address, h->control, ntohs(h->protocol)); 547239462Sdim goto drop; 548239462Sdim } 549239462Sdim 550239462Sdim if (! (ifp->if_flags & IFF_UP) || ! inq) 551239462Sdim goto drop; 552249423Sdim 553249423Sdim /* Check queue. */ 554249423Sdim s = splimp(); 555249423Sdim if (IF_QFULL (inq)) { 556249423Sdim /* Queue overflow. */ 557239462Sdim IF_DROP(inq); 558239462Sdim splx(s); 559239462Sdim if (debug) 560239462Sdim log(LOG_DEBUG, "%s%d: protocol queue overflow\n", 561239462Sdim ifp->if_name, ifp->if_unit); 562239462Sdim goto drop; 563239462Sdim } 564239462Sdim IF_ENQUEUE(inq, m); 565239462Sdim splx(s); 566239462Sdim} 567239462Sdim 568239462Sdim/* 569239462Sdim * Enqueue transmit packet. 570239462Sdim */ 571239462Sdimstatic int 572239462Sdimsppp_output(struct ifnet *ifp, struct mbuf *m, 573239462Sdim struct sockaddr *dst, struct rtentry *rt) 574239462Sdim{ 575239462Sdim struct sppp *sp = (struct sppp*) ifp; 576239462Sdim struct ppp_header *h; 577239462Sdim struct ifqueue *ifq; 578239462Sdim int s, rv = 0; 579239462Sdim 580239462Sdim s = splimp(); 581239462Sdim 582239462Sdim if ((ifp->if_flags & IFF_UP) == 0 || 583239462Sdim (ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == 0) { 584239462Sdim m_freem (m); 585239462Sdim splx (s); 586239462Sdim return (ENETDOWN); 587239462Sdim } 588239462Sdim 589239462Sdim if ((ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == IFF_AUTO) { 590239462Sdim /* 591239462Sdim * Interface is not yet running, but auto-dial. Need 592239462Sdim * to start LCP for it. 593239462Sdim */ 594239462Sdim ifp->if_flags |= IFF_RUNNING; 595239462Sdim splx(s); 596239462Sdim lcp.Open(sp); 597239462Sdim s = splimp(); 598239462Sdim } 599239462Sdim 600239462Sdim ifq = &ifp->if_snd; 601239462Sdim#ifdef INET 602239462Sdim /* 603239462Sdim * Put low delay, telnet, rlogin and ftp control packets 604239462Sdim * in front of the queue. 605239462Sdim */ 606239462Sdim if (dst->sa_family == AF_INET) { 607239462Sdim struct ip *ip = mtod (m, struct ip*); 608239462Sdim struct tcphdr *tcp = (struct tcphdr*) ((long*)ip + ip->ip_hl); 609239462Sdim 610239462Sdim if (! IF_QFULL (&sp->pp_fastq) && 611239462Sdim ((ip->ip_tos & IPTOS_LOWDELAY) || 612239462Sdim ip->ip_p == IPPROTO_TCP && 613239462Sdim m->m_len >= sizeof (struct ip) + sizeof (struct tcphdr) && 614243830Sdim (INTERACTIVE (ntohs (tcp->th_sport)) || 615243830Sdim INTERACTIVE (ntohs (tcp->th_dport))))) 616243830Sdim ifq = &sp->pp_fastq; 617243830Sdim } 618243830Sdim#endif 619243830Sdim 620243830Sdim /* 621243830Sdim * Prepend general data packet PPP header. For now, IP only. 622243830Sdim */ 623243830Sdim M_PREPEND (m, PPP_HEADER_LEN, M_DONTWAIT); 624243830Sdim if (! m) { 625243830Sdim if (ifp->if_flags & IFF_DEBUG) 626243830Sdim log(LOG_DEBUG, "%s%d: no memory for transmit header\n", 627243830Sdim ifp->if_name, ifp->if_unit); 628243830Sdim ++ifp->if_oerrors; 629249423Sdim splx (s); 630263508Sdim return (ENOBUFS); 631263508Sdim } 632249423Sdim h = mtod (m, struct ppp_header*); 633249423Sdim if (sp->pp_flags & PP_CISCO) { 634263508Sdim h->address = CISCO_UNICAST; /* unicast address */ 635263508Sdim h->control = 0; 636249423Sdim } else { 637249423Sdim h->address = PPP_ALLSTATIONS; /* broadcast address */ 638239462Sdim h->control = PPP_UI; /* Unnumbered Info */ 639239462Sdim } 640239462Sdim 641239462Sdim switch (dst->sa_family) { 642239462Sdim#ifdef INET 643239462Sdim case AF_INET: /* Internet Protocol */ 644239462Sdim if (sp->pp_flags & PP_CISCO) 645239462Sdim h->protocol = htons (ETHERTYPE_IP); 646239462Sdim else { 647239462Sdim /* 648239462Sdim * Don't choke with an ENETDOWN early. It's 649239462Sdim * possible that we just started dialing out, 650239462Sdim * so don't drop the packet immediately. If 651239462Sdim * we notice that we run out of buffer space 652239462Sdim * below, we will however remember that we are 653239462Sdim * not ready to carry IP packets, and return 654239462Sdim * ENETDOWN, as opposed to ENOBUFS. 655239462Sdim */ 656239462Sdim h->protocol = htons(PPP_IP); 657239462Sdim if (sp->state[IDX_IPCP] != STATE_OPENED) 658239462Sdim rv = ENETDOWN; 659239462Sdim } 660239462Sdim break; 661239462Sdim#endif 662239462Sdim#ifdef NS 663239462Sdim case AF_NS: /* Xerox NS Protocol */ 664239462Sdim h->protocol = htons ((sp->pp_flags & PP_CISCO) ? 665239462Sdim ETHERTYPE_NS : PPP_XNS); 666239462Sdim break; 667239462Sdim#endif 668239462Sdim#ifdef IPX 669239462Sdim case AF_IPX: /* Novell IPX Protocol */ 670239462Sdim h->protocol = htons ((sp->pp_flags & PP_CISCO) ? 671239462Sdim ETHERTYPE_IPX : PPP_IPX); 672239462Sdim break; 673239462Sdim#endif 674239462Sdim#ifdef ISO 675239462Sdim case AF_ISO: /* ISO OSI Protocol */ 676239462Sdim if (sp->pp_flags & PP_CISCO) 677239462Sdim goto nosupport; 678239462Sdim h->protocol = htons (PPP_ISO); 679239462Sdim break; 680249423Sdimnosupport: 681239462Sdim#endif 682249423Sdim default: 683249423Sdim m_freem (m); 684249423Sdim ++ifp->if_oerrors; 685249423Sdim splx (s); 686249423Sdim return (EAFNOSUPPORT); 687239462Sdim } 688239462Sdim 689239462Sdim /* 690239462Sdim * Queue message on interface, and start output if interface 691239462Sdim * not yet active. 692239462Sdim */ 693239462Sdim if (IF_QFULL (ifq)) { 694239462Sdim IF_DROP (&ifp->if_snd); 695239462Sdim m_freem (m); 696239462Sdim ++ifp->if_oerrors; 697239462Sdim splx (s); 698239462Sdim return (rv? rv: ENOBUFS); 699239462Sdim } 700239462Sdim IF_ENQUEUE (ifq, m); 701239462Sdim if (! (ifp->if_flags & IFF_OACTIVE)) 702249423Sdim (*ifp->if_start) (ifp); 703249423Sdim 704249423Sdim /* 705249423Sdim * Count output packets and bytes. 706239462Sdim * The packet length includes header, FCS and 1 flag, 707239462Sdim * according to RFC 1333. 708239462Sdim */ 709239462Sdim ifp->if_obytes += m->m_pkthdr.len + 3; 710239462Sdim splx (s); 711239462Sdim return (0); 712239462Sdim} 713239462Sdim 714239462Sdimvoid 715239462Sdimsppp_attach(struct ifnet *ifp) 716239462Sdim{ 717239462Sdim struct sppp *sp = (struct sppp*) ifp; 718249423Sdim 719249423Sdim /* Initialize keepalive handler. */ 720249423Sdim if (! spppq) 721249423Sdim keepalive_ch = timeout(sppp_keepalive, 0, hz * 10); 722239462Sdim 723239462Sdim /* Insert new entry into the keepalive list. */ 724239462Sdim sp->pp_next = spppq; 725239462Sdim spppq = sp; 726239462Sdim 727239462Sdim sp->pp_if.if_type = IFT_PPP; 728239462Sdim sp->pp_if.if_output = sppp_output; 729239462Sdim sp->pp_fastq.ifq_maxlen = 32; 730239462Sdim sp->pp_cpq.ifq_maxlen = 20; 731239462Sdim sp->pp_loopcnt = 0; 732239462Sdim sp->pp_alivecnt = 0; 733239462Sdim sp->pp_seq = 0; 734239462Sdim sp->pp_rseq = 0; 735239462Sdim sp->pp_phase = PHASE_DEAD; 736239462Sdim sp->pp_up = lcp.Up; 737239462Sdim sp->pp_down = lcp.Down; 738239462Sdim 739239462Sdim sppp_lcp_init(sp); 740239462Sdim sppp_ipcp_init(sp); 741239462Sdim sppp_pap_init(sp); 742249423Sdim sppp_chap_init(sp); 743239462Sdim} 744239462Sdim 745239462Sdimvoid 746239462Sdimsppp_detach(struct ifnet *ifp) 747249423Sdim{ 748249423Sdim struct sppp **q, *p, *sp = (struct sppp*) ifp; 749249423Sdim int i; 750249423Sdim 751249423Sdim /* Remove the entry from the keepalive list. */ 752249423Sdim for (q = &spppq; (p = *q); q = &p->pp_next) 753239462Sdim if (p == sp) { 754239462Sdim *q = p->pp_next; 755239462Sdim break; 756239462Sdim } 757239462Sdim 758239462Sdim /* Stop keepalive handler. */ 759239462Sdim if (! spppq) 760239462Sdim untimeout(sppp_keepalive, 0, keepalive_ch); 761239462Sdim 762239462Sdim for (i = 0; i < IDX_COUNT; i++) 763239462Sdim untimeout((cps[i])->TO, (void *)sp, sp->ch[i]); 764239462Sdim untimeout(sppp_pap_my_TO, (void *)sp, sp->pap_my_to_ch); 765239462Sdim} 766239462Sdim 767239462Sdim/* 768239462Sdim * Flush the interface output queue. 769239462Sdim */ 770239462Sdimvoid 771239462Sdimsppp_flush(struct ifnet *ifp) 772239462Sdim{ 773239462Sdim struct sppp *sp = (struct sppp*) ifp; 774239462Sdim 775239462Sdim sppp_qflush (&sp->pp_if.if_snd); 776239462Sdim sppp_qflush (&sp->pp_fastq); 777239462Sdim sppp_qflush (&sp->pp_cpq); 778239462Sdim} 779239462Sdim 780239462Sdim/* 781239462Sdim * Check if the output queue is empty. 782239462Sdim */ 783239462Sdimint 784239462Sdimsppp_isempty(struct ifnet *ifp) 785239462Sdim{ 786239462Sdim struct sppp *sp = (struct sppp*) ifp; 787239462Sdim int empty, s; 788239462Sdim 789239462Sdim s = splimp(); 790239462Sdim empty = !sp->pp_fastq.ifq_head && !sp->pp_cpq.ifq_head && 791239462Sdim !sp->pp_if.if_snd.ifq_head; 792239462Sdim splx(s); 793249423Sdim return (empty); 794249423Sdim} 795249423Sdim 796249423Sdim/* 797249423Sdim * Get next packet to send. 798239462Sdim */ 799239462Sdimstruct mbuf * 800239462Sdimsppp_dequeue(struct ifnet *ifp) 801239462Sdim{ 802239462Sdim struct sppp *sp = (struct sppp*) ifp; 803239462Sdim struct mbuf *m; 804239462Sdim int s; 805239462Sdim 806239462Sdim s = splimp(); 807239462Sdim /* 808239462Sdim * Process only the control protocol queue until we have at 809239462Sdim * least one NCP open. 810239462Sdim * 811239462Sdim * Do always serve all three queues in Cisco mode. 812239462Sdim */ 813239462Sdim IF_DEQUEUE(&sp->pp_cpq, m); 814239462Sdim if (m == NULL && 815239462Sdim (sppp_ncp_check(sp) || (sp->pp_flags & PP_CISCO) != 0)) { 816239462Sdim IF_DEQUEUE(&sp->pp_fastq, m); 817239462Sdim if (m == NULL) 818239462Sdim IF_DEQUEUE (&sp->pp_if.if_snd, m); 819239462Sdim } 820239462Sdim splx(s); 821239462Sdim return m; 822239462Sdim} 823239462Sdim 824249423Sdim/* 825239462Sdim * Pick the next packet, do not remove it from the queue. 826239462Sdim */ 827239462Sdimstruct mbuf * 828239462Sdimsppp_pick(struct ifnet *ifp) 829239462Sdim{ 830239462Sdim struct sppp *sp = (struct sppp*)ifp; 831239462Sdim struct mbuf *m; 832239462Sdim int s; 833239462Sdim 834263508Sdim s= splimp (); 835239462Sdim 836263508Sdim m = sp->pp_cpq.ifq_head; 837263508Sdim if (m == NULL && 838239462Sdim (sp->pp_phase == PHASE_NETWORK || 839249423Sdim (sp->pp_flags & PP_CISCO) != 0)) 840239462Sdim if ((m = sp->pp_fastq.ifq_head) == NULL) 841239462Sdim m = sp->pp_if.if_snd.ifq_head; 842239462Sdim splx (s); 843239462Sdim return (m); 844239462Sdim} 845239462Sdim 846263508Sdim/* 847263508Sdim * Process an ioctl request. Called on low priority level. 848263508Sdim */ 849239462Sdimint 850239462Sdimsppp_ioctl(struct ifnet *ifp, int cmd, void *data) 851239462Sdim{ 852239462Sdim struct ifreq *ifr = (struct ifreq*) data; 853249423Sdim struct sppp *sp = (struct sppp*) ifp; 854263508Sdim int s, rv, going_up, going_down, newmode; 855263508Sdim 856263508Sdim s = splimp(); 857263508Sdim rv = 0; 858239462Sdim switch (cmd) { 859239462Sdim case SIOCAIFADDR: 860239462Sdim case SIOCSIFDSTADDR: 861249423Sdim break; 862239462Sdim 863239462Sdim case SIOCSIFADDR: 864239462Sdim if_up(ifp); 865239462Sdim /* fall through... */ 866243830Sdim 867243830Sdim case SIOCSIFFLAGS: 868239462Sdim going_up = ifp->if_flags & IFF_UP && 869239462Sdim (ifp->if_flags & IFF_RUNNING) == 0; 870239462Sdim going_down = (ifp->if_flags & IFF_UP) == 0 && 871239462Sdim ifp->if_flags & IFF_RUNNING; 872239462Sdim newmode = ifp->if_flags & (IFF_AUTO | IFF_PASSIVE); 873243830Sdim if (newmode == (IFF_AUTO | IFF_PASSIVE)) { 874243830Sdim /* sanity */ 875243830Sdim newmode = IFF_PASSIVE; 876243830Sdim ifp->if_flags &= ~IFF_AUTO; 877243830Sdim } 878243830Sdim 879243830Sdim if (going_up || going_down) 880249423Sdim lcp.Close(sp); 881243830Sdim if (going_up && newmode == 0) { 882239462Sdim /* neither auto-dial nor passive */ 883239462Sdim ifp->if_flags |= IFF_RUNNING; 884239462Sdim if (!(sp->pp_flags & PP_CISCO)) 885239462Sdim lcp.Open(sp); 886239462Sdim } else if (going_down) { 887239462Sdim sppp_flush(ifp); 888239462Sdim ifp->if_flags &= ~IFF_RUNNING; 889239462Sdim } 890249423Sdim 891243830Sdim break; 892249423Sdim 893249423Sdim#ifdef SIOCSIFMTU 894249423Sdim#ifndef ifr_mtu 895249423Sdim#define ifr_mtu ifr_metric 896243830Sdim#endif 897243830Sdim case SIOCSIFMTU: 898243830Sdim if (ifr->ifr_mtu < 128 || ifr->ifr_mtu > sp->lcp.their_mru) 899243830Sdim return (EINVAL); 900249423Sdim ifp->if_mtu = ifr->ifr_mtu; 901249423Sdim break; 902249423Sdim#endif 903249423Sdim#ifdef SLIOCSETMTU 904249423Sdim case SLIOCSETMTU: 905249423Sdim if (*(short*)data < 128 || *(short*)data > sp->lcp.their_mru) 906249423Sdim return (EINVAL); 907249423Sdim ifp->if_mtu = *(short*)data; 908249423Sdim break; 909249423Sdim#endif 910249423Sdim#ifdef SIOCGIFMTU 911243830Sdim case SIOCGIFMTU: 912243830Sdim ifr->ifr_mtu = ifp->if_mtu; 913249423Sdim break; 914249423Sdim#endif 915243830Sdim#ifdef SLIOCGETMTU 916249423Sdim case SLIOCGETMTU: 917243830Sdim *(short*)data = ifp->if_mtu; 918243830Sdim break; 919243830Sdim#endif 920249423Sdim case SIOCADDMULTI: 921249423Sdim case SIOCDELMULTI: 922243830Sdim break; 923249423Sdim 924243830Sdim case SIOCGIFGENERIC: 925249423Sdim case SIOCSIFGENERIC: 926243830Sdim rv = sppp_params(sp, cmd, data); 927243830Sdim break; 928243830Sdim 929249423Sdim default: 930249423Sdim rv = ENOTTY; 931249423Sdim } 932249423Sdim splx(s); 933249423Sdim return rv; 934249423Sdim} 935249423Sdim 936249423Sdim 937249423Sdim/* 938249423Sdim * Cisco framing implementation. 939249423Sdim */ 940249423Sdim 941249423Sdim/* 942243830Sdim * Handle incoming Cisco keepalive protocol packets. 943249423Sdim */ 944243830Sdimstatic void 945243830Sdimsppp_cisco_input(struct sppp *sp, struct mbuf *m) 946243830Sdim{ 947249423Sdim STDDCL; 948243830Sdim struct cisco_packet *h; 949243830Sdim u_long me, mymask; 950243830Sdim 951249423Sdim if (m->m_pkthdr.len < CISCO_PACKET_LEN) { 952243830Sdim if (debug) 953243830Sdim log(LOG_DEBUG, 954249423Sdim "%s%d: cisco invalid packet length: %d bytes\n", 955249423Sdim ifp->if_name, ifp->if_unit, m->m_pkthdr.len); 956249423Sdim return; 957249423Sdim } 958249423Sdim h = mtod (m, struct cisco_packet*); 959249423Sdim if (debug) 960263508Sdim log(LOG_DEBUG, 961263508Sdim "%s%d: cisco input: %d bytes " 962263508Sdim "<0x%lx 0x%lx 0x%lx 0x%x 0x%x-0x%x>\n", 963263508Sdim ifp->if_name, ifp->if_unit, m->m_pkthdr.len, 964263508Sdim ntohl (h->type), h->par1, h->par2, h->rel, 965263508Sdim h->time0, h->time1); 966263508Sdim switch (ntohl (h->type)) { 967263508Sdim default: 968249423Sdim if (debug) 969249423Sdim addlog("%s%d: cisco unknown packet type: 0x%lx\n", 970249423Sdim ifp->if_name, ifp->if_unit, ntohl (h->type)); 971249423Sdim break; 972249423Sdim case CISCO_ADDR_REPLY: 973249423Sdim /* Reply on address request, ignore */ 974243830Sdim break; 975239462Sdim case CISCO_KEEPALIVE_REQ: 976239462Sdim sp->pp_alivecnt = 0; 977239462Sdim sp->pp_rseq = ntohl (h->par1); 978239462Sdim if (sp->pp_seq == sp->pp_rseq) { 979239462Sdim /* Local and remote sequence numbers are equal. 980239462Sdim * Probably, the line is in loopback mode. */ 981249423Sdim if (sp->pp_loopcnt >= MAXALIVECNT) { 982249423Sdim printf ("%s%d: loopback\n", 983239462Sdim ifp->if_name, ifp->if_unit); 984249423Sdim sp->pp_loopcnt = 0; 985249423Sdim if (ifp->if_flags & IFF_UP) { 986249423Sdim if_down (ifp); 987249423Sdim sppp_qflush (&sp->pp_cpq); 988239462Sdim } 989239462Sdim } 990249423Sdim ++sp->pp_loopcnt; 991249423Sdim 992239462Sdim /* Generate new local sequence number */ 993239462Sdim read_random((char*)&sp->pp_seq, sizeof sp->pp_seq); 994239462Sdim break; 995239462Sdim } 996243830Sdim sp->pp_loopcnt = 0; 997243830Sdim if (! (ifp->if_flags & IFF_UP) && 998263508Sdim (ifp->if_flags & IFF_RUNNING)) { 999243830Sdim if_up(ifp); 1000243830Sdim printf ("%s%d: up\n", ifp->if_name, ifp->if_unit); 1001243830Sdim } 1002243830Sdim break; 1003243830Sdim case CISCO_ADDR_REQ: 1004243830Sdim sppp_get_ip_addrs(sp, &me, 0, &mymask); 1005243830Sdim if (me != 0L) 1006243830Sdim sppp_cisco_send(sp, CISCO_ADDR_REPLY, me, mymask); 1007243830Sdim break; 1008243830Sdim } 1009243830Sdim} 1010243830Sdim 1011243830Sdim/* 1012249423Sdim * Send Cisco keepalive packet. 1013249423Sdim */ 1014243830Sdimstatic void 1015243830Sdimsppp_cisco_send(struct sppp *sp, int type, long par1, long par2) 1016239462Sdim{ 1017239462Sdim STDDCL; 1018239462Sdim struct ppp_header *h; 1019239462Sdim struct cisco_packet *ch; 1020239462Sdim struct mbuf *m; 1021239462Sdim struct timeval tv; 1022239462Sdim 1023243830Sdim getmicroruntime(&tv); 1024239462Sdim 1025239462Sdim MGETHDR (m, M_DONTWAIT, MT_DATA); 1026239462Sdim if (! m) 1027239462Sdim return; 1028239462Sdim m->m_pkthdr.len = m->m_len = PPP_HEADER_LEN + CISCO_PACKET_LEN; 1029239462Sdim m->m_pkthdr.rcvif = 0; 1030243830Sdim 1031243830Sdim h = mtod (m, struct ppp_header*); 1032239462Sdim h->address = CISCO_MULTICAST; 1033263508Sdim h->control = 0; 1034239462Sdim h->protocol = htons (CISCO_KEEPALIVE); 1035239462Sdim 1036239462Sdim ch = (struct cisco_packet*) (h + 1); 1037239462Sdim ch->type = htonl (type); 1038243830Sdim ch->par1 = htonl (par1); 1039239462Sdim ch->par2 = htonl (par2); 1040239462Sdim ch->rel = -1; 1041239462Sdim ch->time0 = htons ((u_short) (tv.tv_sec >> 16)); 1042239462Sdim ch->time1 = htons ((u_short) tv.tv_sec); 1043239462Sdim 1044239462Sdim if (debug) 1045243830Sdim log(LOG_DEBUG, 1046239462Sdim "%s%d: cisco output: <0x%lx 0x%lx 0x%lx 0x%x 0x%x-0x%x>\n", 1047239462Sdim ifp->if_name, ifp->if_unit, ntohl (ch->type), ch->par1, 1048239462Sdim ch->par2, ch->rel, ch->time0, ch->time1); 1049239462Sdim 1050239462Sdim if (IF_QFULL (&sp->pp_cpq)) { 1051239462Sdim IF_DROP (&sp->pp_fastq); 1052239462Sdim IF_DROP (&ifp->if_snd); 1053239462Sdim m_freem (m); 1054239462Sdim } else 1055239462Sdim IF_ENQUEUE (&sp->pp_cpq, m); 1056239462Sdim if (! (ifp->if_flags & IFF_OACTIVE)) 1057249423Sdim (*ifp->if_start) (ifp); 1058239462Sdim ifp->if_obytes += m->m_pkthdr.len + 3; 1059239462Sdim} 1060239462Sdim 1061249423Sdim/* 1062263508Sdim * PPP protocol implementation. 1063263508Sdim */ 1064249423Sdim 1065263508Sdim/* 1066263508Sdim * Send PPP control protocol packet. 1067263508Sdim */ 1068263508Sdimstatic void 1069263508Sdimsppp_cp_send(struct sppp *sp, u_short proto, u_char type, 1070239462Sdim u_char ident, u_short len, void *data) 1071239462Sdim{ 1072239462Sdim STDDCL; 1073239462Sdim struct ppp_header *h; 1074249423Sdim struct lcp_header *lh; 1075249423Sdim struct mbuf *m; 1076239462Sdim 1077239462Sdim if (len > MHLEN - PPP_HEADER_LEN - LCP_HEADER_LEN) 1078239462Sdim len = MHLEN - PPP_HEADER_LEN - LCP_HEADER_LEN; 1079239462Sdim MGETHDR (m, M_DONTWAIT, MT_DATA); 1080239462Sdim if (! m) 1081239462Sdim return; 1082239462Sdim m->m_pkthdr.len = m->m_len = PPP_HEADER_LEN + LCP_HEADER_LEN + len; 1083239462Sdim m->m_pkthdr.rcvif = 0; 1084239462Sdim 1085239462Sdim h = mtod (m, struct ppp_header*); 1086239462Sdim h->address = PPP_ALLSTATIONS; /* broadcast address */ 1087249423Sdim h->control = PPP_UI; /* Unnumbered Info */ 1088249423Sdim h->protocol = htons (proto); /* Link Control Protocol */ 1089239462Sdim 1090239462Sdim lh = (struct lcp_header*) (h + 1); 1091249423Sdim lh->type = type; 1092249423Sdim lh->ident = ident; 1093249423Sdim lh->len = htons (LCP_HEADER_LEN + len); 1094249423Sdim if (len) 1095249423Sdim bcopy (data, lh+1, len); 1096249423Sdim 1097249423Sdim if (debug) { 1098249423Sdim log(LOG_DEBUG, "%s%d: %s output <%s id=0x%x len=%d", 1099249423Sdim ifp->if_name, ifp->if_unit, 1100249423Sdim sppp_proto_name(proto), 1101249423Sdim sppp_cp_type_name (lh->type), lh->ident, 1102249423Sdim ntohs (lh->len)); 1103249423Sdim if (len) 1104249423Sdim sppp_print_bytes ((u_char*) (lh+1), len); 1105249423Sdim addlog(">\n"); 1106249423Sdim } 1107249423Sdim if (IF_QFULL (&sp->pp_cpq)) { 1108249423Sdim IF_DROP (&sp->pp_fastq); 1109263508Sdim IF_DROP (&ifp->if_snd); 1110249423Sdim m_freem (m); 1111249423Sdim ++ifp->if_oerrors; 1112249423Sdim } else 1113249423Sdim IF_ENQUEUE (&sp->pp_cpq, m); 1114249423Sdim if (! (ifp->if_flags & IFF_OACTIVE)) 1115249423Sdim (*ifp->if_start) (ifp); 1116249423Sdim ifp->if_obytes += m->m_pkthdr.len + 3; 1117249423Sdim} 1118249423Sdim 1119249423Sdim/* 1120249423Sdim * Handle incoming PPP control protocol packets. 1121249423Sdim */ 1122249423Sdimstatic void 1123249423Sdimsppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m) 1124263508Sdim{ 1125263508Sdim STDDCL; 1126263508Sdim struct lcp_header *h; 1127263508Sdim int len = m->m_pkthdr.len; 1128263508Sdim int rv; 1129263508Sdim u_char *p; 1130249423Sdim 1131249423Sdim if (len < 4) { 1132239462Sdim if (debug) 1133239462Sdim log(LOG_DEBUG, 1134249423Sdim "%s%d: %s invalid packet length: %d bytes\n", 1135249423Sdim ifp->if_name, ifp->if_unit, cp->name, len); 1136239462Sdim return; 1137239462Sdim } 1138239462Sdim h = mtod (m, struct lcp_header*); 1139243830Sdim if (debug) { 1140243830Sdim log(LOG_DEBUG, 1141243830Sdim "%s%d: %s input(%s): <%s id=0x%x len=%d", 1142239462Sdim ifp->if_name, ifp->if_unit, cp->name, 1143239462Sdim sppp_state_name(sp->state[cp->protoidx]), 1144249423Sdim sppp_cp_type_name (h->type), h->ident, ntohs (h->len)); 1145249423Sdim if (len > 4) 1146249423Sdim sppp_print_bytes ((u_char*) (h+1), len-4); 1147249423Sdim addlog(">\n"); 1148249423Sdim } 1149239462Sdim if (len > ntohs (h->len)) 1150239462Sdim len = ntohs (h->len); 1151249423Sdim p = (u_char *)(h + 1); 1152249423Sdim switch (h->type) { 1153249423Sdim case CONF_REQ: 1154249423Sdim if (len < 4) { 1155249423Sdim if (debug) 1156249423Sdim addlog("%s%d: %s invalid conf-req length %d\n", 1157249423Sdim ifp->if_name, ifp->if_unit, cp->name, 1158249423Sdim len); 1159249423Sdim ++ifp->if_ierrors; 1160239462Sdim break; 1161249423Sdim } 1162249423Sdim /* handle states where RCR doesn't get a SCA/SCN */ 1163239462Sdim switch (sp->state[cp->protoidx]) { 1164239462Sdim case STATE_CLOSING: 1165239462Sdim case STATE_STOPPING: 1166239462Sdim return; 1167239462Sdim case STATE_CLOSED: 1168239462Sdim sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 1169239462Sdim 0, 0); 1170239462Sdim return; 1171239462Sdim } 1172239462Sdim rv = (cp->RCR)(sp, h, len); 1173239462Sdim switch (sp->state[cp->protoidx]) { 1174239462Sdim case STATE_OPENED: 1175239462Sdim (cp->tld)(sp); 1176239462Sdim (cp->scr)(sp); 1177239462Sdim /* fall through... */ 1178239462Sdim case STATE_ACK_SENT: 1179239462Sdim case STATE_REQ_SENT: 1180239462Sdim sppp_cp_change_state(cp, sp, rv? 1181239462Sdim STATE_ACK_SENT: STATE_REQ_SENT); 1182239462Sdim break; 1183239462Sdim case STATE_STOPPED: 1184249423Sdim sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; 1185239462Sdim (cp->scr)(sp); 1186239462Sdim sppp_cp_change_state(cp, sp, rv? 1187239462Sdim STATE_ACK_SENT: STATE_REQ_SENT); 1188239462Sdim break; 1189239462Sdim case STATE_ACK_RCVD: 1190239462Sdim if (rv) { 1191239462Sdim sppp_cp_change_state(cp, sp, STATE_OPENED); 1192239462Sdim if (debug) 1193249423Sdim log(LOG_DEBUG, "%s%d: %s tlu\n", 1194239462Sdim ifp->if_name, ifp->if_unit, 1195239462Sdim cp->name); 1196239462Sdim (cp->tlu)(sp); 1197239462Sdim } else 1198239462Sdim sppp_cp_change_state(cp, sp, STATE_ACK_RCVD); 1199239462Sdim break; 1200239462Sdim default: 1201239462Sdim printf("%s%d: %s illegal %s in state %s\n", 1202239462Sdim ifp->if_name, ifp->if_unit, cp->name, 1203239462Sdim sppp_cp_type_name(h->type), 1204239462Sdim sppp_state_name(sp->state[cp->protoidx])); 1205239462Sdim ++ifp->if_ierrors; 1206239462Sdim } 1207239462Sdim break; 1208239462Sdim case CONF_ACK: 1209239462Sdim if (h->ident != sp->confid[cp->protoidx]) { 1210239462Sdim if (debug) 1211239462Sdim addlog("%s%d: %s id mismatch 0x%x != 0x%x\n", 1212239462Sdim ifp->if_name, ifp->if_unit, cp->name, 1213239462Sdim h->ident, sp->confid[cp->protoidx]); 1214239462Sdim ++ifp->if_ierrors; 1215239462Sdim break; 1216239462Sdim } 1217239462Sdim switch (sp->state[cp->protoidx]) { 1218239462Sdim case STATE_CLOSED: 1219249423Sdim case STATE_STOPPED: 1220239462Sdim sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0); 1221239462Sdim break; 1222239462Sdim case STATE_CLOSING: 1223239462Sdim case STATE_STOPPING: 1224239462Sdim break; 1225249423Sdim case STATE_REQ_SENT: 1226249423Sdim sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; 1227249423Sdim sppp_cp_change_state(cp, sp, STATE_ACK_RCVD); 1228249423Sdim break; 1229239462Sdim case STATE_OPENED: 1230239462Sdim (cp->tld)(sp); 1231239462Sdim /* fall through */ 1232239462Sdim case STATE_ACK_RCVD: 1233239462Sdim (cp->scr)(sp); 1234239462Sdim sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1235249423Sdim break; 1236239462Sdim case STATE_ACK_SENT: 1237239462Sdim sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; 1238239462Sdim sppp_cp_change_state(cp, sp, STATE_OPENED); 1239239462Sdim if (debug) 1240239462Sdim log(LOG_DEBUG, "%s%d: %s tlu\n", 1241239462Sdim ifp->if_name, ifp->if_unit, cp->name); 1242249423Sdim (cp->tlu)(sp); 1243239462Sdim break; 1244239462Sdim default: 1245239462Sdim printf("%s%d: %s illegal %s in state %s\n", 1246239462Sdim ifp->if_name, ifp->if_unit, cp->name, 1247239462Sdim sppp_cp_type_name(h->type), 1248239462Sdim sppp_state_name(sp->state[cp->protoidx])); 1249249423Sdim ++ifp->if_ierrors; 1250243830Sdim } 1251249423Sdim break; 1252243830Sdim case CONF_NAK: 1253249423Sdim case CONF_REJ: 1254243830Sdim if (h->ident != sp->confid[cp->protoidx]) { 1255243830Sdim if (debug) 1256249423Sdim addlog("%s%d: %s id mismatch 0x%x != 0x%x\n", 1257249423Sdim ifp->if_name, ifp->if_unit, cp->name, 1258243830Sdim h->ident, sp->confid[cp->protoidx]); 1259243830Sdim ++ifp->if_ierrors; 1260249423Sdim break; 1261249423Sdim } 1262263508Sdim if (h->type == CONF_NAK) 1263263508Sdim (cp->RCN_nak)(sp, h, len); 1264263508Sdim else /* CONF_REJ */ 1265263508Sdim (cp->RCN_rej)(sp, h, len); 1266249423Sdim 1267249423Sdim switch (sp->state[cp->protoidx]) { 1268249423Sdim case STATE_CLOSED: 1269249423Sdim case STATE_STOPPED: 1270249423Sdim sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0); 1271249423Sdim break; 1272239462Sdim case STATE_REQ_SENT: 1273249423Sdim case STATE_ACK_SENT: 1274249423Sdim sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; 1275249423Sdim (cp->scr)(sp); 1276249423Sdim break; 1277249423Sdim case STATE_OPENED: 1278249423Sdim (cp->tld)(sp); 1279239462Sdim /* fall through */ 1280249423Sdim case STATE_ACK_RCVD: 1281249423Sdim sppp_cp_change_state(cp, sp, STATE_ACK_SENT); 1282249423Sdim (cp->scr)(sp); 1283239462Sdim break; 1284249423Sdim case STATE_CLOSING: 1285249423Sdim case STATE_STOPPING: 1286249423Sdim break; 1287249423Sdim default: 1288249423Sdim printf("%s%d: %s illegal %s in state %s\n", 1289249423Sdim ifp->if_name, ifp->if_unit, cp->name, 1290249423Sdim sppp_cp_type_name(h->type), 1291249423Sdim sppp_state_name(sp->state[cp->protoidx])); 1292249423Sdim ++ifp->if_ierrors; 1293249423Sdim } 1294249423Sdim break; 1295249423Sdim 1296249423Sdim case TERM_REQ: 1297249423Sdim switch (sp->state[cp->protoidx]) { 1298249423Sdim case STATE_ACK_RCVD: 1299249423Sdim case STATE_ACK_SENT: 1300249423Sdim sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1301249423Sdim /* fall through */ 1302249423Sdim case STATE_CLOSED: 1303249423Sdim case STATE_STOPPED: 1304249423Sdim case STATE_CLOSING: 1305243830Sdim case STATE_STOPPING: 1306249423Sdim case STATE_REQ_SENT: 1307249423Sdim sta: 1308249423Sdim /* Send Terminate-Ack packet. */ 1309239462Sdim if (debug) 1310249423Sdim log(LOG_DEBUG, "%s%d: %s send terminate-ack\n", 1311239462Sdim ifp->if_name, ifp->if_unit, cp->name); 1312239462Sdim sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0); 1313239462Sdim break; 1314239462Sdim case STATE_OPENED: 1315239462Sdim (cp->tld)(sp); 1316239462Sdim sp->rst_counter[cp->protoidx] = 0; 1317239462Sdim sppp_cp_change_state(cp, sp, STATE_STOPPING); 1318239462Sdim goto sta; 1319239462Sdim break; 1320239462Sdim default: 1321239462Sdim printf("%s%d: %s illegal %s in state %s\n", 1322239462Sdim ifp->if_name, ifp->if_unit, cp->name, 1323239462Sdim sppp_cp_type_name(h->type), 1324239462Sdim sppp_state_name(sp->state[cp->protoidx])); 1325239462Sdim ++ifp->if_ierrors; 1326239462Sdim } 1327239462Sdim break; 1328239462Sdim case TERM_ACK: 1329239462Sdim switch (sp->state[cp->protoidx]) { 1330239462Sdim case STATE_CLOSED: 1331239462Sdim case STATE_STOPPED: 1332239462Sdim case STATE_REQ_SENT: 1333239462Sdim case STATE_ACK_SENT: 1334239462Sdim break; 1335239462Sdim case STATE_CLOSING: 1336239462Sdim (cp->tlf)(sp); 1337239462Sdim sppp_cp_change_state(cp, sp, STATE_CLOSED); 1338239462Sdim break; 1339239462Sdim case STATE_STOPPING: 1340239462Sdim (cp->tlf)(sp); 1341239462Sdim sppp_cp_change_state(cp, sp, STATE_STOPPED); 1342239462Sdim break; 1343239462Sdim case STATE_ACK_RCVD: 1344239462Sdim sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1345239462Sdim break; 1346239462Sdim case STATE_OPENED: 1347239462Sdim (cp->tld)(sp); 1348243830Sdim (cp->scr)(sp); 1349243830Sdim sppp_cp_change_state(cp, sp, STATE_ACK_RCVD); 1350243830Sdim break; 1351243830Sdim default: 1352243830Sdim printf("%s%d: %s illegal %s in state %s\n", 1353243830Sdim ifp->if_name, ifp->if_unit, cp->name, 1354243830Sdim sppp_cp_type_name(h->type), 1355243830Sdim sppp_state_name(sp->state[cp->protoidx])); 1356243830Sdim ++ifp->if_ierrors; 1357243830Sdim } 1358243830Sdim break; 1359239462Sdim case CODE_REJ: 1360239462Sdim case PROTO_REJ: 1361239462Sdim /* XXX catastrophic rejects (RXJ-) aren't handled yet. */ 1362239462Sdim log(LOG_INFO, 1363239462Sdim "%s%d: %s: ignoring RXJ (%s) for proto 0x%x, " 1364239462Sdim "danger will robinson\n", 1365239462Sdim ifp->if_name, ifp->if_unit, cp->name, 1366239462Sdim sppp_cp_type_name(h->type), ntohs(*((u_short *)p))); 1367239462Sdim switch (sp->state[cp->protoidx]) { 1368239462Sdim case STATE_CLOSED: 1369239462Sdim case STATE_STOPPED: 1370239462Sdim case STATE_REQ_SENT: 1371239462Sdim case STATE_ACK_SENT: 1372239462Sdim case STATE_CLOSING: 1373239462Sdim case STATE_STOPPING: 1374239462Sdim case STATE_OPENED: 1375239462Sdim break; 1376239462Sdim case STATE_ACK_RCVD: 1377239462Sdim sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1378239462Sdim break; 1379239462Sdim default: 1380239462Sdim printf("%s%d: %s illegal %s in state %s\n", 1381239462Sdim ifp->if_name, ifp->if_unit, cp->name, 1382239462Sdim sppp_cp_type_name(h->type), 1383239462Sdim sppp_state_name(sp->state[cp->protoidx])); 1384239462Sdim ++ifp->if_ierrors; 1385239462Sdim } 1386239462Sdim break; 1387239462Sdim case DISC_REQ: 1388239462Sdim if (cp->proto != PPP_LCP) 1389239462Sdim goto illegal; 1390239462Sdim /* Discard the packet. */ 1391239462Sdim break; 1392239462Sdim case ECHO_REQ: 1393239462Sdim if (cp->proto != PPP_LCP) 1394239462Sdim goto illegal; 1395239462Sdim if (sp->state[cp->protoidx] != STATE_OPENED) { 1396239462Sdim if (debug) 1397239462Sdim addlog("%s%d: lcp echo req but lcp closed\n", 1398239462Sdim ifp->if_name, ifp->if_unit); 1399239462Sdim ++ifp->if_ierrors; 1400239462Sdim break; 1401239462Sdim } 1402239462Sdim if (len < 8) { 1403239462Sdim if (debug) 1404239462Sdim addlog("%s%d: invalid lcp echo request " 1405239462Sdim "packet length: %d bytes\n", 1406239462Sdim ifp->if_name, ifp->if_unit, len); 1407239462Sdim break; 1408239462Sdim } 1409239462Sdim if (ntohl (*(long*)(h+1)) == sp->lcp.magic) { 1410239462Sdim /* Line loopback mode detected. */ 1411239462Sdim printf("%s%d: loopback\n", ifp->if_name, ifp->if_unit); 1412239462Sdim if_down (ifp); 1413239462Sdim sppp_qflush (&sp->pp_cpq); 1414239462Sdim 1415239462Sdim /* Shut down the PPP link. */ 1416239462Sdim /* XXX */ 1417239462Sdim lcp.Down(sp); 1418239462Sdim lcp.Up(sp); 1419239462Sdim break; 1420239462Sdim } 1421239462Sdim *(long*)(h+1) = htonl (sp->lcp.magic); 1422239462Sdim if (debug) 1423239462Sdim addlog("%s%d: got lcp echo req, sending echo rep\n", 1424239462Sdim ifp->if_name, ifp->if_unit); 1425239462Sdim sppp_cp_send (sp, PPP_LCP, ECHO_REPLY, h->ident, len-4, h+1); 1426239462Sdim break; 1427239462Sdim case ECHO_REPLY: 1428249423Sdim if (cp->proto != PPP_LCP) 1429249423Sdim goto illegal; 1430249423Sdim if (h->ident != sp->lcp.echoid) { 1431249423Sdim ++ifp->if_ierrors; 1432249423Sdim break; 1433249423Sdim } 1434249423Sdim if (len < 8) { 1435249423Sdim if (debug) 1436239462Sdim addlog("%s%d: lcp invalid echo reply " 1437239462Sdim "packet length: %d bytes\n", 1438239462Sdim ifp->if_name, ifp->if_unit, len); 1439239462Sdim break; 1440239462Sdim } 1441249423Sdim if (debug) 1442239462Sdim addlog("%s%d: lcp got echo rep\n", 1443239462Sdim ifp->if_name, ifp->if_unit); 1444239462Sdim if (ntohl (*(long*)(h+1)) != sp->lcp.magic) 1445239462Sdim sp->pp_alivecnt = 0; 1446249423Sdim break; 1447239462Sdim default: 1448239462Sdim /* Unknown packet type -- send Code-Reject packet. */ 1449239462Sdim illegal: 1450249423Sdim if (debug) 1451239462Sdim addlog("%s%d: %c send code-rej for 0x%x\n", 1452239462Sdim ifp->if_name, ifp->if_unit, cp->name, h->type); 1453239462Sdim sppp_cp_send(sp, cp->proto, CODE_REJ, ++sp->pp_seq, 1454239462Sdim m->m_pkthdr.len, h); 1455239462Sdim ++ifp->if_ierrors; 1456243830Sdim } 1457243830Sdim} 1458243830Sdim 1459249423Sdim 1460249423Sdim/* 1461243830Sdim * The generic part of all Up/Down/Open/Close/TO event handlers. 1462243830Sdim * Basically, the state transition handling in the automaton. 1463243830Sdim */ 1464243830Sdimstatic void 1465243830Sdimsppp_up_event(const struct cp *cp, struct sppp *sp) 1466243830Sdim{ 1467243830Sdim STDDCL; 1468249423Sdim 1469249423Sdim if (debug) 1470249423Sdim log(LOG_DEBUG, "%s%d: %s up(%s)\n", 1471249423Sdim ifp->if_name, ifp->if_unit, cp->name, 1472249423Sdim sppp_state_name(sp->state[cp->protoidx])); 1473249423Sdim 1474249423Sdim switch (sp->state[cp->protoidx]) { 1475249423Sdim case STATE_INITIAL: 1476249423Sdim sppp_cp_change_state(cp, sp, STATE_CLOSED); 1477249423Sdim break; 1478249423Sdim case STATE_STARTING: 1479249423Sdim sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; 1480249423Sdim (cp->scr)(sp); 1481249423Sdim sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1482249423Sdim break; 1483249423Sdim default: 1484249423Sdim printf("%s%d: %s illegal up in state %s\n", 1485249423Sdim ifp->if_name, ifp->if_unit, cp->name, 1486249423Sdim sppp_state_name(sp->state[cp->protoidx])); 1487249423Sdim } 1488249423Sdim} 1489249423Sdim 1490249423Sdimstatic void 1491249423Sdimsppp_down_event(const struct cp *cp, struct sppp *sp) 1492249423Sdim{ 1493249423Sdim STDDCL; 1494249423Sdim 1495249423Sdim if (debug) 1496249423Sdim log(LOG_DEBUG, "%s%d: %s down(%s)\n", 1497249423Sdim ifp->if_name, ifp->if_unit, cp->name, 1498249423Sdim sppp_state_name(sp->state[cp->protoidx])); 1499249423Sdim 1500249423Sdim switch (sp->state[cp->protoidx]) { 1501249423Sdim case STATE_CLOSED: 1502249423Sdim case STATE_CLOSING: 1503249423Sdim sppp_cp_change_state(cp, sp, STATE_INITIAL); 1504249423Sdim break; 1505249423Sdim case STATE_STOPPED: 1506249423Sdim (cp->tls)(sp); 1507249423Sdim /* fall through */ 1508249423Sdim case STATE_STOPPING: 1509249423Sdim case STATE_REQ_SENT: 1510249423Sdim case STATE_ACK_RCVD: 1511249423Sdim case STATE_ACK_SENT: 1512249423Sdim sppp_cp_change_state(cp, sp, STATE_STARTING); 1513263508Sdim break; 1514263508Sdim case STATE_OPENED: 1515249423Sdim (cp->tld)(sp); 1516249423Sdim sppp_cp_change_state(cp, sp, STATE_STARTING); 1517249423Sdim break; 1518249423Sdim default: 1519249423Sdim printf("%s%d: %s illegal down in state %s\n", 1520249423Sdim ifp->if_name, ifp->if_unit, cp->name, 1521249423Sdim sppp_state_name(sp->state[cp->protoidx])); 1522243830Sdim } 1523263508Sdim} 1524263508Sdim 1525249423Sdim 1526243830Sdimstatic void 1527243830Sdimsppp_open_event(const struct cp *cp, struct sppp *sp) 1528243830Sdim{ 1529243830Sdim STDDCL; 1530263508Sdim 1531263508Sdim if (debug) 1532249423Sdim log(LOG_DEBUG, "%s%d: %s open(%s)\n", 1533243830Sdim ifp->if_name, ifp->if_unit, cp->name, 1534243830Sdim sppp_state_name(sp->state[cp->protoidx])); 1535243830Sdim 1536263508Sdim switch (sp->state[cp->protoidx]) { 1537263508Sdim case STATE_INITIAL: 1538249423Sdim (cp->tls)(sp); 1539243830Sdim sppp_cp_change_state(cp, sp, STATE_STARTING); 1540243830Sdim break; 1541243830Sdim case STATE_STARTING: 1542249423Sdim break; 1543243830Sdim case STATE_CLOSED: 1544243830Sdim sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; 1545239462Sdim (cp->scr)(sp); 1546239462Sdim sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1547239462Sdim break; 1548239462Sdim case STATE_STOPPED: 1549239462Sdim case STATE_STOPPING: 1550239462Sdim case STATE_REQ_SENT: 1551239462Sdim case STATE_ACK_RCVD: 1552239462Sdim case STATE_ACK_SENT: 1553239462Sdim case STATE_OPENED: 1554239462Sdim break; 1555239462Sdim case STATE_CLOSING: 1556239462Sdim sppp_cp_change_state(cp, sp, STATE_STOPPING); 1557239462Sdim break; 1558239462Sdim } 1559243830Sdim} 1560243830Sdim 1561243830Sdim 1562243830Sdimstatic void 1563243830Sdimsppp_close_event(const struct cp *cp, struct sppp *sp) 1564243830Sdim{ 1565243830Sdim STDDCL; 1566243830Sdim 1567243830Sdim if (debug) 1568243830Sdim log(LOG_DEBUG, "%s%d: %s close(%s)\n", 1569243830Sdim ifp->if_name, ifp->if_unit, cp->name, 1570243830Sdim sppp_state_name(sp->state[cp->protoidx])); 1571243830Sdim 1572243830Sdim switch (sp->state[cp->protoidx]) { 1573243830Sdim case STATE_INITIAL: 1574243830Sdim case STATE_CLOSED: 1575243830Sdim case STATE_CLOSING: 1576243830Sdim break; 1577243830Sdim case STATE_STARTING: 1578243830Sdim (cp->tlf)(sp); 1579243830Sdim sppp_cp_change_state(cp, sp, STATE_INITIAL); 1580243830Sdim break; 1581243830Sdim case STATE_STOPPED: 1582243830Sdim sppp_cp_change_state(cp, sp, STATE_CLOSED); 1583243830Sdim break; 1584243830Sdim case STATE_STOPPING: 1585243830Sdim sppp_cp_change_state(cp, sp, STATE_CLOSING); 1586243830Sdim break; 1587243830Sdim case STATE_OPENED: 1588243830Sdim (cp->tld)(sp); 1589243830Sdim /* fall through */ 1590243830Sdim case STATE_REQ_SENT: 1591243830Sdim case STATE_ACK_RCVD: 1592243830Sdim case STATE_ACK_SENT: 1593243830Sdim sp->rst_counter[cp->protoidx] = sp->lcp.max_terminate; 1594243830Sdim sppp_cp_send(sp, cp->proto, TERM_REQ, ++sp->pp_seq, 0, 0); 1595243830Sdim sppp_cp_change_state(cp, sp, STATE_CLOSING); 1596243830Sdim break; 1597243830Sdim } 1598243830Sdim} 1599243830Sdim 1600243830Sdimstatic void 1601243830Sdimsppp_to_event(const struct cp *cp, struct sppp *sp) 1602243830Sdim{ 1603243830Sdim STDDCL; 1604243830Sdim int s; 1605243830Sdim 1606243830Sdim s = splimp(); 1607243830Sdim if (debug) 1608243830Sdim log(LOG_DEBUG, "%s%d: %s TO(%s) rst_counter = %d\n", 1609243830Sdim ifp->if_name, ifp->if_unit, cp->name, 1610243830Sdim sppp_state_name(sp->state[cp->protoidx]), 1611243830Sdim sp->rst_counter[cp->protoidx]); 1612243830Sdim 1613243830Sdim if (--sp->rst_counter[cp->protoidx] < 0) 1614243830Sdim /* TO- event */ 1615243830Sdim switch (sp->state[cp->protoidx]) { 1616243830Sdim case STATE_CLOSING: 1617243830Sdim (cp->tlf)(sp); 1618243830Sdim sppp_cp_change_state(cp, sp, STATE_CLOSED); 1619243830Sdim break; 1620243830Sdim case STATE_STOPPING: 1621239462Sdim (cp->tlf)(sp); 1622239462Sdim sppp_cp_change_state(cp, sp, STATE_STOPPED); 1623249423Sdim break; 1624249423Sdim case STATE_REQ_SENT: 1625249423Sdim case STATE_ACK_RCVD: 1626239462Sdim case STATE_ACK_SENT: 1627239462Sdim (cp->tlf)(sp); 1628239462Sdim sppp_cp_change_state(cp, sp, STATE_STOPPED); 1629239462Sdim break; 1630239462Sdim } 1631239462Sdim else 1632239462Sdim /* TO+ event */ 1633239462Sdim switch (sp->state[cp->protoidx]) { 1634249423Sdim case STATE_CLOSING: 1635239462Sdim case STATE_STOPPING: 1636239462Sdim sppp_cp_send(sp, cp->proto, TERM_REQ, ++sp->pp_seq, 1637239462Sdim 0, 0); 1638239462Sdim sp->ch[cp->protoidx] = timeout(cp->TO, (void *)sp, 1639239462Sdim sp->lcp.timeout); 1640243830Sdim break; 1641243830Sdim case STATE_REQ_SENT: 1642243830Sdim case STATE_ACK_RCVD: 1643239462Sdim (cp->scr)(sp); 1644239462Sdim /* sppp_cp_change_state() will restart the timer */ 1645239462Sdim sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1646239462Sdim break; 1647239462Sdim case STATE_ACK_SENT: 1648239462Sdim (cp->scr)(sp); 1649239462Sdim sp->ch[cp->protoidx] = timeout(cp->TO, (void *)sp, 1650239462Sdim sp->lcp.timeout); 1651239462Sdim break; 1652239462Sdim } 1653239462Sdim 1654239462Sdim splx(s); 1655239462Sdim} 1656239462Sdim 1657243830Sdim/* 1658243830Sdim * Change the state of a control protocol in the state automaton. 1659239462Sdim * Takes care of starting/stopping the restart timer. 1660243830Sdim */ 1661249423Sdimvoid 1662239462Sdimsppp_cp_change_state(const struct cp *cp, struct sppp *sp, int newstate) 1663239462Sdim{ 1664239462Sdim sp->state[cp->protoidx] = newstate; 1665239462Sdim 1666239462Sdim untimeout(cp->TO, (void *)sp, sp->ch[cp->protoidx]); 1667239462Sdim switch (newstate) { 1668239462Sdim case STATE_INITIAL: 1669239462Sdim case STATE_STARTING: 1670249423Sdim case STATE_CLOSED: 1671239462Sdim case STATE_STOPPED: 1672249423Sdim case STATE_OPENED: 1673249423Sdim break; 1674239462Sdim case STATE_CLOSING: 1675239462Sdim case STATE_STOPPING: 1676239462Sdim case STATE_REQ_SENT: 1677239462Sdim case STATE_ACK_RCVD: 1678239462Sdim case STATE_ACK_SENT: 1679239462Sdim sp->ch[cp->protoidx] = timeout(cp->TO, (void *)sp, 1680239462Sdim sp->lcp.timeout); 1681239462Sdim break; 1682239462Sdim } 1683239462Sdim} 1684239462Sdim/* 1685239462Sdim *--------------------------------------------------------------------------* 1686239462Sdim * * 1687239462Sdim * The LCP implementation. * 1688239462Sdim * * 1689239462Sdim *--------------------------------------------------------------------------* 1690239462Sdim */ 1691249423Sdimstatic void 1692239462Sdimsppp_lcp_init(struct sppp *sp) 1693239462Sdim{ 1694249423Sdim sp->lcp.opts = (1 << LCP_OPT_MAGIC); 1695239462Sdim sp->lcp.magic = 0; 1696239462Sdim sp->state[IDX_LCP] = STATE_INITIAL; 1697249423Sdim sp->fail_counter[IDX_LCP] = 0; 1698239462Sdim sp->lcp.protos = 0; 1699 sp->lcp.mru = sp->lcp.their_mru = PP_MTU; 1700 1701 /* 1702 * Initialize counters and timeout values. Note that we don't 1703 * use the 3 seconds suggested in RFC 1661 since we are likely 1704 * running on a fast link. XXX We should probably implement 1705 * the exponential backoff option. Note that these values are 1706 * relevant for all control protocols, not just LCP only. 1707 */ 1708 sp->lcp.timeout = 1 * hz; 1709 sp->lcp.max_terminate = 2; 1710 sp->lcp.max_configure = 10; 1711 sp->lcp.max_failure = 10; 1712 callout_handle_init(&sp->ch[IDX_LCP]); 1713} 1714 1715static void 1716sppp_lcp_up(struct sppp *sp) 1717{ 1718 STDDCL; 1719 1720 /* 1721 * If this interface is passive or dial-on-demand, and we are 1722 * still in Initial state, it means we've got an incoming 1723 * call. Activate the interface. 1724 */ 1725 if ((ifp->if_flags & (IFF_AUTO | IFF_PASSIVE)) != 0) { 1726 if (debug) 1727 log(LOG_DEBUG, 1728 "%s%d: Up event", ifp->if_name, ifp->if_unit); 1729 ifp->if_flags |= IFF_RUNNING; 1730 if (sp->state[IDX_LCP] == STATE_INITIAL) { 1731 if (debug) 1732 addlog("(incoming call)\n"); 1733 sp->pp_flags |= PP_CALLIN; 1734 lcp.Open(sp); 1735 } else if (debug) 1736 addlog("\n"); 1737 } 1738 1739 sppp_up_event(&lcp, sp); 1740} 1741 1742static void 1743sppp_lcp_down(struct sppp *sp) 1744{ 1745 STDDCL; 1746 1747 sppp_down_event(&lcp, sp); 1748 1749 /* 1750 * If this is neither a dial-on-demand nor a passive 1751 * interface, simulate an ``ifconfig down'' action, so the 1752 * administrator can force a redial by another ``ifconfig 1753 * up''. XXX For leased line operation, should we immediately 1754 * try to reopen the connection here? 1755 */ 1756 if ((ifp->if_flags & (IFF_AUTO | IFF_PASSIVE)) == 0) { 1757 log(LOG_INFO, 1758 "%s%d: Down event (carrier loss), taking interface down.\n", 1759 ifp->if_name, ifp->if_unit); 1760 if_down(ifp); 1761 } else { 1762 if (debug) 1763 log(LOG_DEBUG, 1764 "%s%d: Down event (carrier loss)\n", 1765 ifp->if_name, ifp->if_unit); 1766 } 1767 sp->pp_flags &= ~PP_CALLIN; 1768 if (sp->state[IDX_LCP] != STATE_INITIAL) 1769 lcp.Close(sp); 1770 ifp->if_flags &= ~IFF_RUNNING; 1771} 1772 1773static void 1774sppp_lcp_open(struct sppp *sp) 1775{ 1776 /* 1777 * If we are authenticator, negotiate LCP_AUTH 1778 */ 1779 if (sp->hisauth.proto != 0) 1780 sp->lcp.opts |= (1 << LCP_OPT_AUTH_PROTO); 1781 else 1782 sp->lcp.opts &= ~(1 << LCP_OPT_AUTH_PROTO); 1783 sp->pp_flags &= ~PP_NEEDAUTH; 1784 sppp_open_event(&lcp, sp); 1785} 1786 1787static void 1788sppp_lcp_close(struct sppp *sp) 1789{ 1790 sppp_close_event(&lcp, sp); 1791} 1792 1793static void 1794sppp_lcp_TO(void *cookie) 1795{ 1796 sppp_to_event(&lcp, (struct sppp *)cookie); 1797} 1798 1799/* 1800 * Analyze a configure request. Return true if it was agreeable, and 1801 * caused action sca, false if it has been rejected or nak'ed, and 1802 * caused action scn. (The return value is used to make the state 1803 * transition decision in the state automaton.) 1804 */ 1805static int 1806sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len) 1807{ 1808 STDDCL; 1809 u_char *buf, *r, *p; 1810 int origlen, rlen; 1811 u_long nmagic; 1812 u_short authproto; 1813 1814 len -= 4; 1815 origlen = len; 1816 buf = r = malloc (len, M_TEMP, M_NOWAIT); 1817 if (! buf) 1818 return (0); 1819 1820 if (debug) 1821 log(LOG_DEBUG, "%s%d: lcp parse opts: ", 1822 ifp->if_name, ifp->if_unit); 1823 1824 /* pass 1: check for things that need to be rejected */ 1825 p = (void*) (h+1); 1826 for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) { 1827 if (debug) 1828 addlog(" %s ", sppp_lcp_opt_name(*p)); 1829 switch (*p) { 1830 case LCP_OPT_MAGIC: 1831 /* Magic number. */ 1832 /* fall through, both are same length */ 1833 case LCP_OPT_ASYNC_MAP: 1834 /* Async control character map. */ 1835 if (len >= 6 || p[1] == 6) 1836 continue; 1837 if (debug) 1838 addlog("[invalid] "); 1839 break; 1840 case LCP_OPT_MRU: 1841 /* Maximum receive unit. */ 1842 if (len >= 4 && p[1] == 4) 1843 continue; 1844 if (debug) 1845 addlog("[invalid] "); 1846 break; 1847 case LCP_OPT_AUTH_PROTO: 1848 if (len < 4) { 1849 if (debug) 1850 addlog("[invalid] "); 1851 break; 1852 } 1853 authproto = (p[2] << 8) + p[3]; 1854 if (authproto == PPP_CHAP && p[1] != 5) { 1855 if (debug) 1856 addlog("[invalid chap len] "); 1857 break; 1858 } 1859 if (sp->myauth.proto == 0) { 1860 /* we are not configured to do auth */ 1861 if (debug) 1862 addlog("[not configured] "); 1863 break; 1864 } 1865 /* 1866 * Remote want us to authenticate, remember this, 1867 * so we stay in PHASE_AUTHENTICATE after LCP got 1868 * up. 1869 */ 1870 sp->pp_flags |= PP_NEEDAUTH; 1871 continue; 1872 default: 1873 /* Others not supported. */ 1874 if (debug) 1875 addlog("[rej] "); 1876 break; 1877 } 1878 /* Add the option to rejected list. */ 1879 bcopy (p, r, p[1]); 1880 r += p[1]; 1881 rlen += p[1]; 1882 } 1883 if (rlen) { 1884 if (debug) 1885 addlog(" send conf-rej\n"); 1886 sppp_cp_send (sp, PPP_LCP, CONF_REJ, h->ident, rlen, buf); 1887 return 0; 1888 } else if (debug) 1889 addlog("\n"); 1890 1891 /* 1892 * pass 2: check for option values that are unacceptable and 1893 * thus require to be nak'ed. 1894 */ 1895 if (debug) 1896 log(LOG_DEBUG, "%s%d: lcp parse opt values: ", 1897 ifp->if_name, ifp->if_unit); 1898 1899 p = (void*) (h+1); 1900 len = origlen; 1901 for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) { 1902 if (debug) 1903 addlog(" %s ", sppp_lcp_opt_name(*p)); 1904 switch (*p) { 1905 case LCP_OPT_MAGIC: 1906 /* Magic number -- extract. */ 1907 nmagic = (u_long)p[2] << 24 | 1908 (u_long)p[3] << 16 | p[4] << 8 | p[5]; 1909 if (nmagic != sp->lcp.magic) { 1910 if (debug) 1911 addlog("0x%x ", nmagic); 1912 continue; 1913 } 1914 /* 1915 * Local and remote magics equal -- loopback? 1916 */ 1917 if (sp->pp_loopcnt >= MAXALIVECNT*5) { 1918 printf ("%s%d: loopback\n", 1919 ifp->if_name, ifp->if_unit); 1920 sp->pp_loopcnt = 0; 1921 if (ifp->if_flags & IFF_UP) { 1922 if_down(ifp); 1923 sppp_qflush(&sp->pp_cpq); 1924 /* XXX ? */ 1925 lcp.Down(sp); 1926 lcp.Up(sp); 1927 } 1928 } else if (debug) 1929 addlog("[glitch] "); 1930 ++sp->pp_loopcnt; 1931 /* 1932 * We negate our magic here, and NAK it. If 1933 * we see it later in an NAK packet, we 1934 * suggest a new one. 1935 */ 1936 nmagic = ~sp->lcp.magic; 1937 /* Gonna NAK it. */ 1938 p[2] = nmagic >> 24; 1939 p[3] = nmagic >> 16; 1940 p[4] = nmagic >> 8; 1941 p[5] = nmagic; 1942 break; 1943 1944 case LCP_OPT_ASYNC_MAP: 1945 /* Async control character map -- check to be zero. */ 1946 if (! p[2] && ! p[3] && ! p[4] && ! p[5]) { 1947 if (debug) 1948 addlog("[empty] "); 1949 continue; 1950 } 1951 if (debug) 1952 addlog("[non-empty] "); 1953 /* suggest a zero one */ 1954 p[2] = p[3] = p[4] = p[5] = 0; 1955 break; 1956 1957 case LCP_OPT_MRU: 1958 /* 1959 * Maximum receive unit. Always agreeable, 1960 * but ignored by now. 1961 */ 1962 sp->lcp.their_mru = p[2] * 256 + p[3]; 1963 if (debug) 1964 addlog("%d ", sp->lcp.their_mru); 1965 continue; 1966 1967 case LCP_OPT_AUTH_PROTO: 1968 authproto = (p[2] << 8) + p[3]; 1969 if (sp->myauth.proto != authproto) { 1970 /* not agreed, nak */ 1971 if (debug) 1972 addlog("[mine %s != his %s] ", 1973 sppp_proto_name(sp->hisauth.proto), 1974 sppp_proto_name(authproto)); 1975 p[2] = sp->myauth.proto >> 8; 1976 p[3] = sp->myauth.proto; 1977 break; 1978 } 1979 if (authproto == PPP_CHAP && p[4] != CHAP_MD5) { 1980 if (debug) 1981 addlog("[chap not MD5] "); 1982 p[4] == CHAP_MD5; 1983 break; 1984 } 1985 continue; 1986 } 1987 /* Add the option to nak'ed list. */ 1988 bcopy (p, r, p[1]); 1989 r += p[1]; 1990 rlen += p[1]; 1991 } 1992 if (rlen) { 1993 if (++sp->fail_counter[IDX_LCP] >= sp->lcp.max_failure) { 1994 if (debug) 1995 addlog(" max_failure (%d) exceeded, " 1996 "send conf-rej\n", 1997 sp->lcp.max_failure); 1998 sppp_cp_send(sp, PPP_LCP, CONF_REJ, h->ident, rlen, buf); 1999 } else { 2000 if (debug) 2001 addlog(" send conf-nak\n"); 2002 sppp_cp_send (sp, PPP_LCP, CONF_NAK, h->ident, rlen, buf); 2003 } 2004 return 0; 2005 } else { 2006 if (debug) 2007 addlog(" send conf-ack\n"); 2008 sp->fail_counter[IDX_LCP] = 0; 2009 sp->pp_loopcnt = 0; 2010 sppp_cp_send (sp, PPP_LCP, CONF_ACK, 2011 h->ident, origlen, h+1); 2012 } 2013 2014 free (buf, M_TEMP); 2015 return (rlen == 0); 2016} 2017 2018/* 2019 * Analyze the LCP Configure-Reject option list, and adjust our 2020 * negotiation. 2021 */ 2022static void 2023sppp_lcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) 2024{ 2025 STDDCL; 2026 u_char *buf, *p; 2027 2028 len -= 4; 2029 buf = malloc (len, M_TEMP, M_NOWAIT); 2030 if (!buf) 2031 return; 2032 2033 if (debug) 2034 log(LOG_DEBUG, "%s%d: lcp rej opts: ", 2035 ifp->if_name, ifp->if_unit); 2036 2037 p = (void*) (h+1); 2038 for (; len > 1 && p[1]; len -= p[1], p += p[1]) { 2039 if (debug) 2040 addlog(" %s ", sppp_lcp_opt_name(*p)); 2041 switch (*p) { 2042 case LCP_OPT_MAGIC: 2043 /* Magic number -- can't use it, use 0 */ 2044 sp->lcp.opts &= ~(1 << LCP_OPT_MAGIC); 2045 sp->lcp.magic = 0; 2046 break; 2047 case LCP_OPT_MRU: 2048 /* 2049 * Should not be rejected anyway, since we only 2050 * negotiate a MRU if explicitly requested by 2051 * peer. 2052 */ 2053 sp->lcp.opts &= ~(1 << LCP_OPT_MRU); 2054 break; 2055 case LCP_OPT_AUTH_PROTO: 2056 /* 2057 * Peer doesn't want to authenticate himself, 2058 * deny unless this is a dialout call, and 2059 * AUTHFLAG_NOCALLOUT is set. 2060 */ 2061 if ((sp->pp_flags & PP_CALLIN) == 0 && 2062 (sp->hisauth.flags & AUTHFLAG_NOCALLOUT) != 0) { 2063 if (debug) 2064 addlog("[don't insist on auth " 2065 "for callout]"); 2066 sp->lcp.opts &= ~(1 << LCP_OPT_AUTH_PROTO); 2067 break; 2068 } 2069 if (debug) 2070 addlog("[access denied]\n"); 2071 lcp.Close(sp); 2072 break; 2073 } 2074 } 2075 if (debug) 2076 addlog("\n"); 2077 free (buf, M_TEMP); 2078 return; 2079} 2080 2081/* 2082 * Analyze the LCP Configure-NAK option list, and adjust our 2083 * negotiation. 2084 */ 2085static void 2086sppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) 2087{ 2088 STDDCL; 2089 u_char *buf, *p; 2090 u_long magic; 2091 2092 len -= 4; 2093 buf = malloc (len, M_TEMP, M_NOWAIT); 2094 if (!buf) 2095 return; 2096 2097 if (debug) 2098 log(LOG_DEBUG, "%s%d: lcp nak opts: ", 2099 ifp->if_name, ifp->if_unit); 2100 2101 p = (void*) (h+1); 2102 for (; len > 1 && p[1]; len -= p[1], p += p[1]) { 2103 if (debug) 2104 addlog(" %s ", sppp_lcp_opt_name(*p)); 2105 switch (*p) { 2106 case LCP_OPT_MAGIC: 2107 /* Magic number -- renegotiate */ 2108 if ((sp->lcp.opts & (1 << LCP_OPT_MAGIC)) && 2109 len >= 6 && p[1] == 6) { 2110 magic = (u_long)p[2] << 24 | 2111 (u_long)p[3] << 16 | p[4] << 8 | p[5]; 2112 /* 2113 * If the remote magic is our negated one, 2114 * this looks like a loopback problem. 2115 * Suggest a new magic to make sure. 2116 */ 2117 if (magic == ~sp->lcp.magic) { 2118 if (debug) 2119 addlog("magic glitch "); 2120 read_random((char*)&sp->lcp.magic, sizeof sp->lcp.magic); 2121 } else { 2122 sp->lcp.magic = magic; 2123 if (debug) 2124 addlog("%d "); 2125 } 2126 } 2127 break; 2128 case LCP_OPT_MRU: 2129 /* 2130 * Peer wants to advise us to negotiate an MRU. 2131 * Agree on it if it's reasonable, or use 2132 * default otherwise. 2133 */ 2134 if (len >= 4 && p[1] == 4) { 2135 u_int mru = p[2] * 256 + p[3]; 2136 if (debug) 2137 addlog("%d ", mru); 2138 if (mru < PP_MTU || mru > PP_MAX_MRU) 2139 mru = PP_MTU; 2140 sp->lcp.mru = mru; 2141 sp->lcp.opts |= (1 << LCP_OPT_MRU); 2142 } 2143 break; 2144 case LCP_OPT_AUTH_PROTO: 2145 /* 2146 * Peer doesn't like our authentication method, 2147 * deny. 2148 */ 2149 if (debug) 2150 addlog("[access denied]\n"); 2151 lcp.Close(sp); 2152 break; 2153 } 2154 } 2155 if (debug) 2156 addlog("\n"); 2157 free (buf, M_TEMP); 2158 return; 2159} 2160 2161static void 2162sppp_lcp_tlu(struct sppp *sp) 2163{ 2164 STDDCL; 2165 int i; 2166 u_long mask; 2167 2168 /* XXX ? */ 2169 if (! (ifp->if_flags & IFF_UP) && 2170 (ifp->if_flags & IFF_RUNNING)) { 2171 /* Coming out of loopback mode. */ 2172 if_up(ifp); 2173 printf ("%s%d: up\n", ifp->if_name, ifp->if_unit); 2174 } 2175 2176 for (i = 0; i < IDX_COUNT; i++) 2177 if ((cps[i])->flags & CP_QUAL) 2178 (cps[i])->Open(sp); 2179 2180 if ((sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) != 0 || 2181 (sp->pp_flags & PP_NEEDAUTH) != 0) 2182 sp->pp_phase = PHASE_AUTHENTICATE; 2183 else 2184 sp->pp_phase = PHASE_NETWORK; 2185 2186 log(LOG_INFO, "%s%d: phase %s\n", ifp->if_name, ifp->if_unit, 2187 sppp_phase_name(sp->pp_phase)); 2188 2189 /* 2190 * Open all authentication protocols. This is even required 2191 * if we already proceeded to network phase, since it might be 2192 * that remote wants us to authenticate, so we might have to 2193 * send a PAP request. Undesired authentication protocols 2194 * don't do anything when they get an Open event. 2195 */ 2196 for (i = 0; i < IDX_COUNT; i++) 2197 if ((cps[i])->flags & CP_AUTH) 2198 (cps[i])->Open(sp); 2199 2200 if (sp->pp_phase == PHASE_NETWORK) { 2201 /* Notify all NCPs. */ 2202 for (i = 0; i < IDX_COUNT; i++) 2203 if ((cps[i])->flags & CP_NCP) 2204 (cps[i])->Open(sp); 2205 } 2206 2207 /* Send Up events to all started protos. */ 2208 for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1) 2209 if (sp->lcp.protos & mask && ((cps[i])->flags & CP_LCP) == 0) 2210 (cps[i])->Up(sp); 2211 2212 if (sp->pp_phase == PHASE_NETWORK) 2213 /* if no NCP is starting, close down */ 2214 sppp_lcp_check_and_close(sp); 2215} 2216 2217static void 2218sppp_lcp_tld(struct sppp *sp) 2219{ 2220 STDDCL; 2221 int i; 2222 u_long mask; 2223 2224 sp->pp_phase = PHASE_TERMINATE; 2225 2226 log(LOG_INFO, "%s%d: phase %s\n", ifp->if_name, ifp->if_unit, 2227 sppp_phase_name(sp->pp_phase)); 2228 2229 /* 2230 * Take upper layers down. We send the Down event first and 2231 * the Close second to prevent the upper layers from sending 2232 * ``a flurry of terminate-request packets'', as the RFC 2233 * describes it. 2234 */ 2235 for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1) 2236 if (sp->lcp.protos & mask && ((cps[i])->flags & CP_LCP) == 0) { 2237 (cps[i])->Down(sp); 2238 (cps[i])->Close(sp); 2239 } 2240} 2241 2242static void 2243sppp_lcp_tls(struct sppp *sp) 2244{ 2245 STDDCL; 2246 2247 sp->pp_phase = PHASE_ESTABLISH; 2248 2249 log(LOG_INFO, "%s%d: phase %s\n", ifp->if_name, ifp->if_unit, 2250 sppp_phase_name(sp->pp_phase)); 2251 2252 /* Notify lower layer if desired. */ 2253 if (sp->pp_tls) 2254 (sp->pp_tls)(sp); 2255} 2256 2257static void 2258sppp_lcp_tlf(struct sppp *sp) 2259{ 2260 STDDCL; 2261 2262 sp->pp_phase = PHASE_DEAD; 2263 log(LOG_INFO, "%s%d: phase %s\n", ifp->if_name, ifp->if_unit, 2264 sppp_phase_name(sp->pp_phase)); 2265 2266 /* Notify lower layer if desired. */ 2267 if (sp->pp_tlf) 2268 (sp->pp_tlf)(sp); 2269} 2270 2271static void 2272sppp_lcp_scr(struct sppp *sp) 2273{ 2274 char opt[6 /* magicnum */ + 4 /* mru */ + 5 /* chap */]; 2275 int i = 0; 2276 u_short authproto; 2277 2278 if (sp->lcp.opts & (1 << LCP_OPT_MAGIC)) { 2279 if (! sp->lcp.magic) 2280 read_random((char*)&sp->lcp.magic, sizeof sp->lcp.magic); 2281 opt[i++] = LCP_OPT_MAGIC; 2282 opt[i++] = 6; 2283 opt[i++] = sp->lcp.magic >> 24; 2284 opt[i++] = sp->lcp.magic >> 16; 2285 opt[i++] = sp->lcp.magic >> 8; 2286 opt[i++] = sp->lcp.magic; 2287 } 2288 2289 if (sp->lcp.opts & (1 << LCP_OPT_MRU)) { 2290 opt[i++] = LCP_OPT_MRU; 2291 opt[i++] = 4; 2292 opt[i++] = sp->lcp.mru >> 8; 2293 opt[i++] = sp->lcp.mru; 2294 } 2295 2296 if (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) { 2297 authproto = sp->hisauth.proto; 2298 opt[i++] = LCP_OPT_AUTH_PROTO; 2299 opt[i++] = authproto == PPP_CHAP? 5: 4; 2300 opt[i++] = authproto >> 8; 2301 opt[i++] = authproto; 2302 if (authproto == PPP_CHAP) 2303 opt[i++] = CHAP_MD5; 2304 } 2305 2306 sp->confid[IDX_LCP] = ++sp->pp_seq; 2307 sppp_cp_send (sp, PPP_LCP, CONF_REQ, sp->confid[IDX_LCP], i, &opt); 2308} 2309 2310/* 2311 * Check the open NCPs, return true if at least one NCP is open. 2312 */ 2313static int 2314sppp_ncp_check(struct sppp *sp) 2315{ 2316 int i, mask; 2317 2318 for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1) 2319 if (sp->lcp.protos & mask && (cps[i])->flags & CP_NCP) 2320 return 1; 2321 return 0; 2322} 2323 2324/* 2325 * Re-check the open NCPs and see if we should terminate the link. 2326 * Called by the NCPs during their tlf action handling. 2327 */ 2328static void 2329sppp_lcp_check_and_close(struct sppp *sp) 2330{ 2331 2332 if (sp->pp_phase < PHASE_NETWORK) 2333 /* don't bother, we are already going down */ 2334 return; 2335 2336 if (sppp_ncp_check(sp)) 2337 return; 2338 2339 lcp.Close(sp); 2340} 2341/* 2342 *--------------------------------------------------------------------------* 2343 * * 2344 * The IPCP implementation. * 2345 * * 2346 *--------------------------------------------------------------------------* 2347 */ 2348 2349static void 2350sppp_ipcp_init(struct sppp *sp) 2351{ 2352 sp->ipcp.opts = 0; 2353 sp->ipcp.flags = 0; 2354 sp->state[IDX_IPCP] = STATE_INITIAL; 2355 sp->fail_counter[IDX_IPCP] = 0; 2356 callout_handle_init(&sp->ch[IDX_IPCP]); 2357} 2358 2359static void 2360sppp_ipcp_up(struct sppp *sp) 2361{ 2362 sppp_up_event(&ipcp, sp); 2363} 2364 2365static void 2366sppp_ipcp_down(struct sppp *sp) 2367{ 2368 sppp_down_event(&ipcp, sp); 2369} 2370 2371static void 2372sppp_ipcp_open(struct sppp *sp) 2373{ 2374 STDDCL; 2375 u_long myaddr, hisaddr; 2376 2377 sppp_get_ip_addrs(sp, &myaddr, &hisaddr, 0); 2378 /* 2379 * If we don't have his address, this probably means our 2380 * interface doesn't want to talk IP at all. (This could 2381 * be the case if somebody wants to speak only IPX, for 2382 * example.) Don't open IPCP in this case. 2383 */ 2384 if (hisaddr == 0L) { 2385 /* XXX this message should go away */ 2386 if (debug) 2387 log(LOG_DEBUG, "%s%d: ipcp_open(): no IP interface\n", 2388 ifp->if_name, ifp->if_unit); 2389 return; 2390 } 2391 2392 if (myaddr == 0L) { 2393 /* 2394 * I don't have an assigned address, so i need to 2395 * negotiate my address. 2396 */ 2397 sp->ipcp.flags |= IPCP_MYADDR_DYN; 2398 sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS); 2399 } 2400 sppp_open_event(&ipcp, sp); 2401} 2402 2403static void 2404sppp_ipcp_close(struct sppp *sp) 2405{ 2406 sppp_close_event(&ipcp, sp); 2407 if (sp->ipcp.flags & IPCP_MYADDR_DYN) 2408 /* 2409 * My address was dynamic, clear it again. 2410 */ 2411 sppp_set_ip_addr(sp, 0L); 2412} 2413 2414static void 2415sppp_ipcp_TO(void *cookie) 2416{ 2417 sppp_to_event(&ipcp, (struct sppp *)cookie); 2418} 2419 2420/* 2421 * Analyze a configure request. Return true if it was agreeable, and 2422 * caused action sca, false if it has been rejected or nak'ed, and 2423 * caused action scn. (The return value is used to make the state 2424 * transition decision in the state automaton.) 2425 */ 2426static int 2427sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len) 2428{ 2429 u_char *buf, *r, *p; 2430 struct ifnet *ifp = &sp->pp_if; 2431 int rlen, origlen, debug = ifp->if_flags & IFF_DEBUG; 2432 u_long hisaddr, desiredaddr; 2433 2434 len -= 4; 2435 origlen = len; 2436 /* 2437 * Make sure to allocate a buf that can at least hold a 2438 * conf-nak with an `address' option. We might need it below. 2439 */ 2440 buf = r = malloc ((len < 6? 6: len), M_TEMP, M_NOWAIT); 2441 if (! buf) 2442 return (0); 2443 2444 /* pass 1: see if we can recognize them */ 2445 if (debug) 2446 log(LOG_DEBUG, "%s%d: ipcp parse opts: ", 2447 ifp->if_name, ifp->if_unit); 2448 p = (void*) (h+1); 2449 for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) { 2450 if (debug) 2451 addlog(" %s ", sppp_ipcp_opt_name(*p)); 2452 switch (*p) { 2453#ifdef notyet 2454 case IPCP_OPT_COMPRESSION: 2455 if (len >= 6 && p[1] >= 6) { 2456 /* correctly formed compress option */ 2457 continue; 2458 } 2459 if (debug) 2460 addlog("[invalid] "); 2461 break; 2462#endif 2463 case IPCP_OPT_ADDRESS: 2464 if (len >= 6 && p[1] == 6) { 2465 /* correctly formed address option */ 2466 continue; 2467 } 2468 if (debug) 2469 addlog("[invalid] "); 2470 break; 2471 default: 2472 /* Others not supported. */ 2473 if (debug) 2474 addlog("[rej] "); 2475 break; 2476 } 2477 /* Add the option to rejected list. */ 2478 bcopy (p, r, p[1]); 2479 r += p[1]; 2480 rlen += p[1]; 2481 } 2482 if (rlen) { 2483 if (debug) 2484 addlog(" send conf-rej\n"); 2485 sppp_cp_send (sp, PPP_IPCP, CONF_REJ, h->ident, rlen, buf); 2486 return 0; 2487 } else if (debug) 2488 addlog("\n"); 2489 2490 /* pass 2: parse option values */ 2491 sppp_get_ip_addrs(sp, 0, &hisaddr, 0); 2492 if (debug) 2493 log(LOG_DEBUG, "%s%d: ipcp parse opt values: ", 2494 ifp->if_name, ifp->if_unit); 2495 p = (void*) (h+1); 2496 len = origlen; 2497 for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) { 2498 if (debug) 2499 addlog(" %s ", sppp_ipcp_opt_name(*p)); 2500 switch (*p) { 2501#ifdef notyet 2502 case IPCP_OPT_COMPRESSION: 2503 continue; 2504#endif 2505 case IPCP_OPT_ADDRESS: 2506 desiredaddr = p[2] << 24 | p[3] << 16 | 2507 p[4] << 8 | p[5]; 2508 if (desiredaddr == hisaddr || 2509 hisaddr == 1 && desiredaddr != 0) { 2510 /* 2511 * Peer's address is same as our value, 2512 * or we have set it to 0.0.0.1 to 2513 * indicate that we do not really care, 2514 * this is agreeable. Gonna conf-ack 2515 * it. 2516 */ 2517 if (debug) 2518 addlog("%s [ack] ", 2519 sppp_dotted_quad(desiredaddr)); 2520 /* record that we've seen it already */ 2521 sp->ipcp.flags |= IPCP_HISADDR_SEEN; 2522 continue; 2523 } 2524 /* 2525 * The address wasn't agreeable. This is either 2526 * he sent us 0.0.0.0, asking to assign him an 2527 * address, or he send us another address not 2528 * matching our value. Either case, we gonna 2529 * conf-nak it with our value. 2530 */ 2531 if (debug) { 2532 if (desiredaddr == 0) 2533 addlog("[addr requested] "); 2534 else 2535 addlog("%s [not agreed] ", 2536 sppp_dotted_quad(desiredaddr)); 2537 2538 p[2] = hisaddr >> 24; 2539 p[3] = hisaddr >> 16; 2540 p[4] = hisaddr >> 8; 2541 p[5] = hisaddr; 2542 } 2543 break; 2544 } 2545 /* Add the option to nak'ed list. */ 2546 bcopy (p, r, p[1]); 2547 r += p[1]; 2548 rlen += p[1]; 2549 } 2550 2551 /* 2552 * If we are about to conf-ack the request, but haven't seen 2553 * his address so far, gonna conf-nak it instead, with the 2554 * `address' option present and our idea of his address being 2555 * filled in there, to request negotiation of both addresses. 2556 * 2557 * XXX This can result in an endless req - nak loop if peer 2558 * doesn't want to send us his address. Q: What should we do 2559 * about it? XXX A: implement the max-failure counter. 2560 */ 2561 if (rlen == 0 && !(sp->ipcp.flags & IPCP_HISADDR_SEEN)) { 2562 buf[0] = IPCP_OPT_ADDRESS; 2563 buf[1] = 6; 2564 buf[2] = hisaddr >> 24; 2565 buf[3] = hisaddr >> 16; 2566 buf[4] = hisaddr >> 8; 2567 buf[5] = hisaddr; 2568 rlen = 6; 2569 if (debug) 2570 addlog("still need hisaddr "); 2571 } 2572 2573 if (rlen) { 2574 if (debug) 2575 addlog(" send conf-nak\n"); 2576 sppp_cp_send (sp, PPP_IPCP, CONF_NAK, h->ident, rlen, buf); 2577 } else { 2578 if (debug) 2579 addlog(" send conf-ack\n"); 2580 sppp_cp_send (sp, PPP_IPCP, CONF_ACK, 2581 h->ident, origlen, h+1); 2582 } 2583 2584 free (buf, M_TEMP); 2585 return (rlen == 0); 2586} 2587 2588/* 2589 * Analyze the IPCP Configure-Reject option list, and adjust our 2590 * negotiation. 2591 */ 2592static void 2593sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) 2594{ 2595 u_char *buf, *p; 2596 struct ifnet *ifp = &sp->pp_if; 2597 int debug = ifp->if_flags & IFF_DEBUG; 2598 2599 len -= 4; 2600 buf = malloc (len, M_TEMP, M_NOWAIT); 2601 if (!buf) 2602 return; 2603 2604 if (debug) 2605 log(LOG_DEBUG, "%s%d: ipcp rej opts: ", 2606 ifp->if_name, ifp->if_unit); 2607 2608 p = (void*) (h+1); 2609 for (; len > 1 && p[1]; len -= p[1], p += p[1]) { 2610 if (debug) 2611 addlog(" %s ", sppp_ipcp_opt_name(*p)); 2612 switch (*p) { 2613 case IPCP_OPT_ADDRESS: 2614 /* 2615 * Peer doesn't grok address option. This is 2616 * bad. XXX Should we better give up here? 2617 */ 2618 sp->ipcp.opts &= ~(1 << IPCP_OPT_ADDRESS); 2619 break; 2620#ifdef notyet 2621 case IPCP_OPT_COMPRESS: 2622 sp->ipcp.opts &= ~(1 << IPCP_OPT_COMPRESS); 2623 break; 2624#endif 2625 } 2626 } 2627 if (debug) 2628 addlog("\n"); 2629 free (buf, M_TEMP); 2630 return; 2631} 2632 2633/* 2634 * Analyze the IPCP Configure-NAK option list, and adjust our 2635 * negotiation. 2636 */ 2637static void 2638sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) 2639{ 2640 u_char *buf, *p; 2641 struct ifnet *ifp = &sp->pp_if; 2642 int debug = ifp->if_flags & IFF_DEBUG; 2643 u_long wantaddr; 2644 2645 len -= 4; 2646 buf = malloc (len, M_TEMP, M_NOWAIT); 2647 if (!buf) 2648 return; 2649 2650 if (debug) 2651 log(LOG_DEBUG, "%s%d: ipcp nak opts: ", 2652 ifp->if_name, ifp->if_unit); 2653 2654 p = (void*) (h+1); 2655 for (; len > 1 && p[1]; len -= p[1], p += p[1]) { 2656 if (debug) 2657 addlog(" %s ", sppp_ipcp_opt_name(*p)); 2658 switch (*p) { 2659 case IPCP_OPT_ADDRESS: 2660 /* 2661 * Peer doesn't like our local IP address. See 2662 * if we can do something for him. We'll drop 2663 * him our address then. 2664 */ 2665 if (len >= 6 && p[1] == 6) { 2666 wantaddr = p[2] << 24 | p[3] << 16 | 2667 p[4] << 8 | p[5]; 2668 sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS); 2669 if (debug) 2670 addlog("[wantaddr %s] ", 2671 sppp_dotted_quad(wantaddr)); 2672 /* 2673 * When doing dynamic address assignment, 2674 * we accept his offer. Otherwise, we 2675 * ignore it and thus continue to negotiate 2676 * our already existing value. 2677 */ 2678 if (sp->ipcp.flags & IPCP_MYADDR_DYN) { 2679 sppp_set_ip_addr(sp, wantaddr); 2680 if (debug) 2681 addlog("[agree] "); 2682 } 2683 } 2684 break; 2685#ifdef notyet 2686 case IPCP_OPT_COMPRESS: 2687 /* 2688 * Peer wants different compression parameters. 2689 */ 2690 break; 2691#endif 2692 } 2693 } 2694 if (debug) 2695 addlog("\n"); 2696 free (buf, M_TEMP); 2697 return; 2698} 2699 2700static void 2701sppp_ipcp_tlu(struct sppp *sp) 2702{ 2703} 2704 2705static void 2706sppp_ipcp_tld(struct sppp *sp) 2707{ 2708} 2709 2710static void 2711sppp_ipcp_tls(struct sppp *sp) 2712{ 2713 /* indicate to LCP that it must stay alive */ 2714 sp->lcp.protos |= (1 << IDX_IPCP); 2715} 2716 2717static void 2718sppp_ipcp_tlf(struct sppp *sp) 2719{ 2720 /* we no longer need LCP */ 2721 sp->lcp.protos &= ~(1 << IDX_IPCP); 2722 sppp_lcp_check_and_close(sp); 2723} 2724 2725static void 2726sppp_ipcp_scr(struct sppp *sp) 2727{ 2728 char opt[6 /* compression */ + 6 /* address */]; 2729 u_long ouraddr; 2730 int i = 0; 2731 2732#ifdef notyet 2733 if (sp->ipcp.opts & (1 << IPCP_OPT_COMPRESSION)) { 2734 opt[i++] = IPCP_OPT_COMPRESSION; 2735 opt[i++] = 6; 2736 opt[i++] = 0; /* VJ header compression */ 2737 opt[i++] = 0x2d; /* VJ header compression */ 2738 opt[i++] = max_slot_id; 2739 opt[i++] = comp_slot_id; 2740 } 2741#endif 2742 2743 if (sp->ipcp.opts & (1 << IPCP_OPT_ADDRESS)) { 2744 sppp_get_ip_addrs(sp, &ouraddr, 0, 0); 2745 opt[i++] = IPCP_OPT_ADDRESS; 2746 opt[i++] = 6; 2747 opt[i++] = ouraddr >> 24; 2748 opt[i++] = ouraddr >> 16; 2749 opt[i++] = ouraddr >> 8; 2750 opt[i++] = ouraddr; 2751 } 2752 2753 sp->confid[IDX_IPCP] = ++sp->pp_seq; 2754 sppp_cp_send(sp, PPP_IPCP, CONF_REQ, sp->confid[IDX_IPCP], i, &opt); 2755} 2756 2757 2758/* 2759 *--------------------------------------------------------------------------* 2760 * * 2761 * The CHAP implementation. * 2762 * * 2763 *--------------------------------------------------------------------------* 2764 */ 2765 2766/* 2767 * The authentication protocols don't employ a full-fledged state machine as 2768 * the control protocols do, since they do have Open and Close events, but 2769 * not Up and Down, nor are they explicitly terminated. Also, use of the 2770 * authentication protocols may be different in both directions (this makes 2771 * sense, think of a machine that never accepts incoming calls but only 2772 * calls out, it doesn't require the called party to authenticate itself). 2773 * 2774 * Our state machine for the local authentication protocol (we are requesting 2775 * the peer to authenticate) looks like: 2776 * 2777 * RCA- 2778 * +--------------------------------------------+ 2779 * V scn,tld| 2780 * +--------+ Close +---------+ RCA+ 2781 * | |<----------------------------------| |------+ 2782 * +--->| Closed | TO* | Opened | sca | 2783 * | | |-----+ +-------| |<-----+ 2784 * | +--------+ irc | | +---------+ 2785 * | ^ | | ^ 2786 * | | | | | 2787 * | | | | | 2788 * | TO-| | | | 2789 * | |tld TO+ V | | 2790 * | | +------->+ | | 2791 * | | | | | | 2792 * | +--------+ V | | 2793 * | | |<----+<--------------------+ | 2794 * | | Req- | scr | 2795 * | | Sent | | 2796 * | | | | 2797 * | +--------+ | 2798 * | RCA- | | RCA+ | 2799 * +------+ +------------------------------------------+ 2800 * scn,tld sca,irc,ict,tlu 2801 * 2802 * 2803 * with: 2804 * 2805 * Open: LCP reached authentication phase 2806 * Close: LCP reached terminate phase 2807 * 2808 * RCA+: received reply (pap-req, chap-response), acceptable 2809 * RCN: received reply (pap-req, chap-response), not acceptable 2810 * TO+: timeout with restart counter >= 0 2811 * TO-: timeout with restart counter < 0 2812 * TO*: reschedule timeout for CHAP 2813 * 2814 * scr: send request packet (none for PAP, chap-challenge) 2815 * sca: send ack packet (pap-ack, chap-success) 2816 * scn: send nak packet (pap-nak, chap-failure) 2817 * ict: initialize re-challenge timer (CHAP only) 2818 * 2819 * tlu: this-layer-up, LCP reaches network phase 2820 * tld: this-layer-down, LCP enters terminate phase 2821 * 2822 * Note that in CHAP mode, after sending a new challenge, while the state 2823 * automaton falls back into Req-Sent state, it doesn't signal a tld 2824 * event to LCP, so LCP remains in network phase. Only after not getting 2825 * any response (or after getting an unacceptable response), CHAP closes, 2826 * causing LCP to enter terminate phase. 2827 * 2828 * With PAP, there is no initial request that can be sent. The peer is 2829 * expected to send one based on the successful negotiation of PAP as 2830 * the authentication protocol during the LCP option negotiation. 2831 * 2832 * Incoming authentication protocol requests (remote requests 2833 * authentication, we are peer) don't employ a state machine at all, 2834 * they are simply answered. Some peers [Ascend P50 firmware rev 2835 * 4.50] react allergically when sending IPCP requests while they are 2836 * still in authentication phase (thereby violating the standard that 2837 * demands that these NCP packets are to be discarded), so we keep 2838 * track of the peer demanding us to authenticate, and only proceed to 2839 * phase network once we've seen a positive acknowledge for the 2840 * authentication. 2841 */ 2842 2843/* 2844 * Handle incoming CHAP packets. 2845 */ 2846void 2847sppp_chap_input(struct sppp *sp, struct mbuf *m) 2848{ 2849 STDDCL; 2850 struct lcp_header *h; 2851 int len, x; 2852 u_char *value, *name, digest[AUTHKEYLEN], dsize; 2853 int value_len, name_len; 2854 MD5_CTX ctx; 2855 2856 len = m->m_pkthdr.len; 2857 if (len < 4) { 2858 if (debug) 2859 log(LOG_DEBUG, 2860 "%s%d: chap invalid packet length: %d bytes\n", 2861 ifp->if_name, ifp->if_unit, len); 2862 return; 2863 } 2864 h = mtod (m, struct lcp_header*); 2865 if (len > ntohs (h->len)) 2866 len = ntohs (h->len); 2867 2868 switch (h->type) { 2869 /* challenge, failure and success are his authproto */ 2870 case CHAP_CHALLENGE: 2871 value = 1 + (u_char*)(h+1); 2872 value_len = value[-1]; 2873 name = value + value_len; 2874 name_len = len - value_len - 5; 2875 if (name_len < 0) { 2876 if (debug) { 2877 log(LOG_DEBUG, 2878 "%s%d: chap corrupted challenge " 2879 "<%s id=0x%x len=%d", 2880 ifp->if_name, ifp->if_unit, 2881 sppp_auth_type_name(PPP_CHAP, h->type), 2882 h->ident, ntohs(h->len)); 2883 if (len > 4) 2884 sppp_print_bytes((u_char*) (h+1), len-4); 2885 addlog(">\n"); 2886 } 2887 break; 2888 } 2889 2890 if (debug) { 2891 log(LOG_DEBUG, 2892 "%s%d: chap input <%s id=0x%x len=%d name=", 2893 ifp->if_name, ifp->if_unit, 2894 sppp_auth_type_name(PPP_CHAP, h->type), h->ident, 2895 ntohs(h->len)); 2896 sppp_print_string((char*) name, name_len); 2897 addlog(" value-size=%d value=", value_len); 2898 sppp_print_bytes(value, value_len); 2899 addlog(">\n"); 2900 } 2901 2902 /* Compute reply value. */ 2903 MD5Init(&ctx); 2904 MD5Update(&ctx, &h->ident, 1); 2905 MD5Update(&ctx, sp->myauth.secret, 2906 sppp_strnlen(sp->myauth.secret, AUTHKEYLEN)); 2907 MD5Update(&ctx, value, value_len); 2908 MD5Final(digest, &ctx); 2909 dsize = sizeof digest; 2910 2911 sppp_auth_send(&chap, sp, CHAP_RESPONSE, h->ident, 2912 sizeof dsize, (const char *)&dsize, 2913 sizeof digest, digest, 2914 sppp_strnlen(sp->myauth.name, AUTHNAMELEN), 2915 sp->myauth.name, 2916 0); 2917 break; 2918 2919 case CHAP_SUCCESS: 2920 if (debug) { 2921 log(LOG_DEBUG, "%s%d: chap success", 2922 ifp->if_name, ifp->if_unit); 2923 if (len > 4) { 2924 addlog(": "); 2925 sppp_print_string((char*)(h + 1), len - 4); 2926 } 2927 addlog("\n"); 2928 } 2929 x = splimp(); 2930 sp->pp_flags &= ~PP_NEEDAUTH; 2931 if (sp->myauth.proto == PPP_CHAP && 2932 (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) && 2933 (sp->lcp.protos & (1 << IDX_CHAP)) == 0) { 2934 /* 2935 * We are authenticator for CHAP but didn't 2936 * complete yet. Leave it to tlu to proceed 2937 * to network phase. 2938 */ 2939 splx(x); 2940 break; 2941 } 2942 splx(x); 2943 sppp_phase_network(sp); 2944 break; 2945 2946 case CHAP_FAILURE: 2947 if (debug) { 2948 log(LOG_INFO, "%s%d: chap failure", 2949 ifp->if_name, ifp->if_unit); 2950 if (len > 4) { 2951 addlog(": "); 2952 sppp_print_string((char*)(h + 1), len - 4); 2953 } 2954 addlog("\n"); 2955 } else 2956 log(LOG_INFO, "%s%d: chap failure\n", 2957 ifp->if_name, ifp->if_unit); 2958 /* await LCP shutdown by authenticator */ 2959 break; 2960 2961 /* response is my authproto */ 2962 case CHAP_RESPONSE: 2963 value = 1 + (u_char*)(h+1); 2964 value_len = value[-1]; 2965 name = value + value_len; 2966 name_len = len - value_len - 5; 2967 if (name_len < 0) { 2968 if (debug) { 2969 log(LOG_DEBUG, 2970 "%s%d: chap corrupted response " 2971 "<%s id=0x%x len=%d", 2972 ifp->if_name, ifp->if_unit, 2973 sppp_auth_type_name(PPP_CHAP, h->type), 2974 h->ident, ntohs(h->len)); 2975 if (len > 4) 2976 sppp_print_bytes((u_char*)(h+1), len-4); 2977 addlog(">\n"); 2978 } 2979 break; 2980 } 2981 if (h->ident != sp->confid[IDX_CHAP]) { 2982 if (debug) 2983 log(LOG_DEBUG, 2984 "%s%d: chap dropping response for old ID " 2985 "(got %d, expected %d)\n", 2986 h->ident, sp->confid[IDX_CHAP]); 2987 break; 2988 } 2989 if (name_len != sppp_strnlen(sp->hisauth.name, AUTHNAMELEN) 2990 || bcmp(name, sp->hisauth.name, name_len) != 0) { 2991 log(LOG_INFO, "%s%d: chap response, his name ", 2992 ifp->if_name, ifp->if_unit); 2993 sppp_print_string(name, name_len); 2994 addlog(" != expected "); 2995 sppp_print_string(sp->hisauth.name, 2996 sppp_strnlen(sp->hisauth.name, AUTHNAMELEN)); 2997 addlog("\n"); 2998 } 2999 if (debug) { 3000 log(LOG_DEBUG, "%s%d: chap input(%s) " 3001 "<%s id=0x%x len=%d name=", 3002 ifp->if_name, ifp->if_unit, 3003 sppp_state_name(sp->state[IDX_CHAP]), 3004 sppp_auth_type_name(PPP_CHAP, h->type), 3005 h->ident, ntohs (h->len)); 3006 sppp_print_string((char*)name, name_len); 3007 addlog(" value-size=%d value=", value_len); 3008 sppp_print_bytes(value, value_len); 3009 addlog(">\n"); 3010 } 3011 if (value_len != AUTHKEYLEN) { 3012 if (debug) 3013 log(LOG_DEBUG, 3014 "%s%d: chap bad hash value length: " 3015 "%d bytes, should be %d\n", 3016 ifp->if_name, ifp->if_unit, value_len, 3017 AUTHKEYLEN); 3018 break; 3019 } 3020 3021 MD5Init(&ctx); 3022 MD5Update(&ctx, &h->ident, 1); 3023 MD5Update(&ctx, sp->hisauth.secret, 3024 sppp_strnlen(sp->hisauth.secret, AUTHKEYLEN)); 3025 MD5Update(&ctx, sp->myauth.challenge, AUTHKEYLEN); 3026 MD5Final(digest, &ctx); 3027 3028#define FAILMSG "Failed..." 3029#define SUCCMSG "Welcome!" 3030 3031 if (value_len != sizeof digest || 3032 bcmp(digest, value, value_len) != 0) { 3033 /* action scn, tld */ 3034 sppp_auth_send(&chap, sp, CHAP_FAILURE, h->ident, 3035 sizeof(FAILMSG) - 1, (u_char *)FAILMSG, 3036 0); 3037 chap.tld(sp); 3038 break; 3039 } 3040 /* action sca, perhaps tlu */ 3041 if (sp->state[IDX_CHAP] == STATE_REQ_SENT || 3042 sp->state[IDX_CHAP] == STATE_OPENED) 3043 sppp_auth_send(&chap, sp, CHAP_SUCCESS, h->ident, 3044 sizeof(SUCCMSG) - 1, (u_char *)SUCCMSG, 3045 0); 3046 if (sp->state[IDX_CHAP] == STATE_REQ_SENT) { 3047 sppp_cp_change_state(&chap, sp, STATE_OPENED); 3048 chap.tlu(sp); 3049 } 3050 break; 3051 3052 default: 3053 /* Unknown CHAP packet type -- ignore. */ 3054 if (debug) { 3055 log(LOG_DEBUG, "%s%d: chap unknown input(%s) " 3056 "<0x%x id=0x%xh len=%d", 3057 ifp->if_name, ifp->if_unit, 3058 sppp_state_name(sp->state[IDX_CHAP]), 3059 h->type, h->ident, ntohs(h->len)); 3060 if (len > 4) 3061 sppp_print_bytes((u_char*)(h+1), len-4); 3062 addlog(">\n"); 3063 } 3064 break; 3065 3066 } 3067} 3068 3069static void 3070sppp_chap_init(struct sppp *sp) 3071{ 3072 /* Chap doesn't have STATE_INITIAL at all. */ 3073 sp->state[IDX_CHAP] = STATE_CLOSED; 3074 sp->fail_counter[IDX_CHAP] = 0; 3075 callout_handle_init(&sp->ch[IDX_CHAP]); 3076} 3077 3078static void 3079sppp_chap_open(struct sppp *sp) 3080{ 3081 if (sp->myauth.proto == PPP_CHAP && 3082 (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) != 0) { 3083 /* we are authenticator for CHAP, start it */ 3084 chap.scr(sp); 3085 sp->rst_counter[IDX_CHAP] = sp->lcp.max_configure; 3086 sppp_cp_change_state(&chap, sp, STATE_REQ_SENT); 3087 } 3088 /* nothing to be done if we are peer, await a challenge */ 3089} 3090 3091static void 3092sppp_chap_close(struct sppp *sp) 3093{ 3094 if (sp->state[IDX_CHAP] != STATE_CLOSED) 3095 sppp_cp_change_state(&chap, sp, STATE_CLOSED); 3096} 3097 3098static void 3099sppp_chap_TO(void *cookie) 3100{ 3101 struct sppp *sp = (struct sppp *)cookie; 3102 STDDCL; 3103 int s; 3104 3105 s = splimp(); 3106 if (debug) 3107 log(LOG_DEBUG, "%s%d: chap TO(%s) rst_counter = %d\n", 3108 ifp->if_name, ifp->if_unit, 3109 sppp_state_name(sp->state[IDX_CHAP]), 3110 sp->rst_counter[IDX_CHAP]); 3111 3112 if (--sp->rst_counter[IDX_CHAP] < 0) 3113 /* TO- event */ 3114 switch (sp->state[IDX_CHAP]) { 3115 case STATE_REQ_SENT: 3116 chap.tld(sp); 3117 sppp_cp_change_state(&chap, sp, STATE_CLOSED); 3118 break; 3119 } 3120 else 3121 /* TO+ (or TO*) event */ 3122 switch (sp->state[IDX_CHAP]) { 3123 case STATE_OPENED: 3124 /* TO* event */ 3125 sp->rst_counter[IDX_CHAP] = sp->lcp.max_configure; 3126 /* fall through */ 3127 case STATE_REQ_SENT: 3128 chap.scr(sp); 3129 /* sppp_cp_change_state() will restart the timer */ 3130 sppp_cp_change_state(&chap, sp, STATE_REQ_SENT); 3131 break; 3132 } 3133 3134 splx(s); 3135} 3136 3137static void 3138sppp_chap_tlu(struct sppp *sp) 3139{ 3140 STDDCL; 3141 int i, x; 3142 3143 sp->rst_counter[IDX_CHAP] = sp->lcp.max_configure; 3144 3145 /* 3146 * Some broken CHAP implementations (Conware CoNet, firmware 3147 * 4.0.?) don't want to re-authenticate their CHAP once the 3148 * initial challenge-response exchange has taken place. 3149 * Provide for an option to avoid rechallenges. 3150 */ 3151 if ((sp->hisauth.flags & AUTHFLAG_NORECHALLENGE) == 0) { 3152 /* 3153 * Compute the re-challenge timeout. This will yield 3154 * a number between 300 and 810 seconds. 3155 */ 3156 i = 300 + ((unsigned)(random() & 0xff00) >> 7); 3157 3158 sp->ch[IDX_CHAP] = timeout(chap.TO, (void *)sp, i * hz); 3159 } 3160 3161 if (debug) { 3162 log(LOG_DEBUG, 3163 "%s%d: chap %s, ", 3164 ifp->if_name, ifp->if_unit, 3165 sp->pp_phase == PHASE_NETWORK? "reconfirmed": "tlu"); 3166 if ((sp->hisauth.flags & AUTHFLAG_NORECHALLENGE) == 0) 3167 addlog("next re-challenge in %d seconds\n", i); 3168 else 3169 addlog("re-challenging supressed\n"); 3170 } 3171 3172 x = splimp(); 3173 /* indicate to LCP that we need to be closed down */ 3174 sp->lcp.protos |= (1 << IDX_CHAP); 3175 3176 if (sp->pp_flags & PP_NEEDAUTH) { 3177 /* 3178 * Remote is authenticator, but his auth proto didn't 3179 * complete yet. Defer the transition to network 3180 * phase. 3181 */ 3182 splx(x); 3183 return; 3184 } 3185 splx(x); 3186 3187 /* 3188 * If we are already in phase network, we are done here. This 3189 * is the case if this is a dummy tlu event after a re-challenge. 3190 */ 3191 if (sp->pp_phase != PHASE_NETWORK) 3192 sppp_phase_network(sp); 3193} 3194 3195static void 3196sppp_chap_tld(struct sppp *sp) 3197{ 3198 STDDCL; 3199 3200 if (debug) 3201 log(LOG_DEBUG, "%s%d: chap tld\n", ifp->if_name, ifp->if_unit); 3202 untimeout(chap.TO, (void *)sp, sp->ch[IDX_CHAP]); 3203 sp->lcp.protos &= ~(1 << IDX_CHAP); 3204 3205 lcp.Close(sp); 3206} 3207 3208static void 3209sppp_chap_scr(struct sppp *sp) 3210{ 3211 struct timeval tv; 3212 u_long *ch, seed; 3213 u_char clen; 3214 3215 /* Compute random challenge. */ 3216 ch = (u_long *)sp->myauth.challenge; 3217 microtime(&tv); 3218 seed = tv.tv_sec ^ tv.tv_usec; 3219 ch[0] = seed ^ random(); 3220 ch[1] = seed ^ random(); 3221 ch[2] = seed ^ random(); 3222 ch[3] = seed ^ random(); 3223 clen = AUTHKEYLEN; 3224 3225 sp->confid[IDX_CHAP] = ++sp->pp_seq; 3226 3227 sppp_auth_send(&chap, sp, CHAP_CHALLENGE, sp->confid[IDX_CHAP], 3228 sizeof clen, (const char *)&clen, 3229 AUTHKEYLEN, sp->myauth.challenge, 3230 sppp_strnlen(sp->myauth.name, AUTHNAMELEN), 3231 sp->myauth.name, 3232 0); 3233} 3234/* 3235 *--------------------------------------------------------------------------* 3236 * * 3237 * The PAP implementation. * 3238 * * 3239 *--------------------------------------------------------------------------* 3240 */ 3241/* 3242 * For PAP, we need to keep a little state also if we are the peer, not the 3243 * authenticator. This is since we don't get a request to authenticate, but 3244 * have to repeatedly authenticate ourself until we got a response (or the 3245 * retry counter is expired). 3246 */ 3247 3248/* 3249 * Handle incoming PAP packets. */ 3250static void 3251sppp_pap_input(struct sppp *sp, struct mbuf *m) 3252{ 3253 STDDCL; 3254 struct lcp_header *h; 3255 int len, x; 3256 u_char *name, *passwd, mlen; 3257 int name_len, passwd_len; 3258 3259 len = m->m_pkthdr.len; 3260 if (len < 5) { 3261 if (debug) 3262 log(LOG_DEBUG, 3263 "%s%d: pap invalid packet length: %d bytes\n", 3264 ifp->if_name, ifp->if_unit, len); 3265 return; 3266 } 3267 h = mtod (m, struct lcp_header*); 3268 if (len > ntohs (h->len)) 3269 len = ntohs (h->len); 3270 switch (h->type) { 3271 /* PAP request is my authproto */ 3272 case PAP_REQ: 3273 name = 1 + (u_char*)(h+1); 3274 name_len = name[-1]; 3275 passwd = name + name_len + 1; 3276 if (name_len > len - 6 || 3277 (passwd_len = passwd[-1]) > len - 6 - name_len) { 3278 if (debug) { 3279 log(LOG_DEBUG, "%s%d: pap corrupted input " 3280 "<%s id=0x%x len=%d", 3281 ifp->if_name, ifp->if_unit, 3282 sppp_auth_type_name(PPP_PAP, h->type), 3283 h->ident, ntohs(h->len)); 3284 if (len > 4) 3285 sppp_print_bytes((u_char*)(h+1), len-4); 3286 addlog(">\n"); 3287 } 3288 break; 3289 } 3290 if (debug) { 3291 log(LOG_DEBUG, "%s%d: pap input(%s) " 3292 "<%s id=0x%x len=%d name=", 3293 ifp->if_name, ifp->if_unit, 3294 sppp_state_name(sp->state[IDX_PAP]), 3295 sppp_auth_type_name(PPP_PAP, h->type), 3296 h->ident, ntohs(h->len)); 3297 sppp_print_string((char*)name, name_len); 3298 addlog(" passwd="); 3299 sppp_print_string((char*)passwd, passwd_len); 3300 addlog(">\n"); 3301 } 3302 if (name_len > AUTHNAMELEN || 3303 passwd_len > AUTHKEYLEN || 3304 bcmp(name, sp->hisauth.name, name_len) != 0 || 3305 bcmp(passwd, sp->hisauth.secret, passwd_len) != 0) { 3306 /* action scn, tld */ 3307 mlen = sizeof(FAILMSG) - 1; 3308 sppp_auth_send(&pap, sp, PAP_NAK, h->ident, 3309 sizeof mlen, (const char *)&mlen, 3310 sizeof(FAILMSG) - 1, (u_char *)FAILMSG, 3311 0); 3312 pap.tld(sp); 3313 break; 3314 } 3315 /* action sca, perhaps tlu */ 3316 if (sp->state[IDX_PAP] == STATE_REQ_SENT || 3317 sp->state[IDX_PAP] == STATE_OPENED) { 3318 mlen = sizeof(SUCCMSG) - 1; 3319 sppp_auth_send(&pap, sp, PAP_ACK, h->ident, 3320 sizeof mlen, (const char *)&mlen, 3321 sizeof(SUCCMSG) - 1, (u_char *)SUCCMSG, 3322 0); 3323 } 3324 if (sp->state[IDX_PAP] == STATE_REQ_SENT) { 3325 sppp_cp_change_state(&pap, sp, STATE_OPENED); 3326 pap.tlu(sp); 3327 } 3328 break; 3329 3330 /* ack and nak are his authproto */ 3331 case PAP_ACK: 3332 untimeout(sppp_pap_my_TO, (void *)sp, sp->pap_my_to_ch); 3333 if (debug) { 3334 log(LOG_DEBUG, "%s%d: pap success", 3335 ifp->if_name, ifp->if_unit); 3336 name_len = *((char *)h); 3337 if (len > 5 && name_len) { 3338 addlog(": "); 3339 sppp_print_string((char*)(h+1), name_len); 3340 } 3341 addlog("\n"); 3342 } 3343 x = splimp(); 3344 sp->pp_flags &= ~PP_NEEDAUTH; 3345 if (sp->myauth.proto == PPP_PAP && 3346 (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) && 3347 (sp->lcp.protos & (1 << IDX_PAP)) == 0) { 3348 /* 3349 * We are authenticator for PAP but didn't 3350 * complete yet. Leave it to tlu to proceed 3351 * to network phase. 3352 */ 3353 splx(x); 3354 break; 3355 } 3356 splx(x); 3357 sppp_phase_network(sp); 3358 break; 3359 3360 case PAP_NAK: 3361 untimeout(sppp_pap_my_TO, (void *)sp, sp->pap_my_to_ch); 3362 if (debug) { 3363 log(LOG_INFO, "%s%d: pap failure", 3364 ifp->if_name, ifp->if_unit); 3365 name_len = *((char *)h); 3366 if (len > 5 && name_len) { 3367 addlog(": "); 3368 sppp_print_string((char*)(h+1), name_len); 3369 } 3370 addlog("\n"); 3371 } else 3372 log(LOG_INFO, "%s%d: pap failure\n", 3373 ifp->if_name, ifp->if_unit); 3374 /* await LCP shutdown by authenticator */ 3375 break; 3376 3377 default: 3378 /* Unknown PAP packet type -- ignore. */ 3379 if (debug) { 3380 log(LOG_DEBUG, "%s%d: pap corrupted input " 3381 "<0x%x id=0x%x len=%d", 3382 ifp->if_name, ifp->if_unit, 3383 h->type, h->ident, ntohs(h->len)); 3384 if (len > 4) 3385 sppp_print_bytes((u_char*)(h+1), len-4); 3386 addlog(">\n"); 3387 } 3388 break; 3389 3390 } 3391} 3392 3393static void 3394sppp_pap_init(struct sppp *sp) 3395{ 3396 /* PAP doesn't have STATE_INITIAL at all. */ 3397 sp->state[IDX_PAP] = STATE_CLOSED; 3398 sp->fail_counter[IDX_PAP] = 0; 3399 callout_handle_init(&sp->ch[IDX_PAP]); 3400 callout_handle_init(&sp->pap_my_to_ch); 3401} 3402 3403static void 3404sppp_pap_open(struct sppp *sp) 3405{ 3406 if (sp->hisauth.proto == PPP_PAP && 3407 (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) != 0) { 3408 /* we are authenticator for PAP, start our timer */ 3409 sp->rst_counter[IDX_PAP] = sp->lcp.max_configure; 3410 sppp_cp_change_state(&pap, sp, STATE_REQ_SENT); 3411 } 3412 if (sp->myauth.proto == PPP_PAP) { 3413 /* we are peer, send a request, and start a timer */ 3414 pap.scr(sp); 3415 sp->pap_my_to_ch = timeout(sppp_pap_my_TO, (void *)sp, 3416 sp->lcp.timeout); 3417 } 3418} 3419 3420static void 3421sppp_pap_close(struct sppp *sp) 3422{ 3423 if (sp->state[IDX_PAP] != STATE_CLOSED) 3424 sppp_cp_change_state(&pap, sp, STATE_CLOSED); 3425} 3426 3427/* 3428 * That's the timeout routine if we are authenticator. Since the 3429 * authenticator is basically passive in PAP, we can't do much here. 3430 */ 3431static void 3432sppp_pap_TO(void *cookie) 3433{ 3434 struct sppp *sp = (struct sppp *)cookie; 3435 STDDCL; 3436 int s; 3437 3438 s = splimp(); 3439 if (debug) 3440 log(LOG_DEBUG, "%s%d: pap TO(%s) rst_counter = %d\n", 3441 ifp->if_name, ifp->if_unit, 3442 sppp_state_name(sp->state[IDX_PAP]), 3443 sp->rst_counter[IDX_PAP]); 3444 3445 if (--sp->rst_counter[IDX_PAP] < 0) 3446 /* TO- event */ 3447 switch (sp->state[IDX_PAP]) { 3448 case STATE_REQ_SENT: 3449 pap.tld(sp); 3450 sppp_cp_change_state(&pap, sp, STATE_CLOSED); 3451 break; 3452 } 3453 else 3454 /* TO+ event, not very much we could do */ 3455 switch (sp->state[IDX_PAP]) { 3456 case STATE_REQ_SENT: 3457 /* sppp_cp_change_state() will restart the timer */ 3458 sppp_cp_change_state(&pap, sp, STATE_REQ_SENT); 3459 break; 3460 } 3461 3462 splx(s); 3463} 3464 3465/* 3466 * That's the timeout handler if we are peer. Since the peer is active, 3467 * we need to retransmit our PAP request since it is apparently lost. 3468 * XXX We should impose a max counter. 3469 */ 3470static void 3471sppp_pap_my_TO(void *cookie) 3472{ 3473 struct sppp *sp = (struct sppp *)cookie; 3474 STDDCL; 3475 3476 if (debug) 3477 log(LOG_DEBUG, "%s%d: pap peer TO\n", 3478 ifp->if_name, ifp->if_unit); 3479 3480 pap.scr(sp); 3481} 3482 3483static void 3484sppp_pap_tlu(struct sppp *sp) 3485{ 3486 STDDCL; 3487 int x; 3488 3489 sp->rst_counter[IDX_PAP] = sp->lcp.max_configure; 3490 3491 if (debug) 3492 log(LOG_DEBUG, "%s%d: %s tlu\n", 3493 ifp->if_name, ifp->if_unit, pap.name); 3494 3495 x = splimp(); 3496 /* indicate to LCP that we need to be closed down */ 3497 sp->lcp.protos |= (1 << IDX_PAP); 3498 3499 if (sp->pp_flags & PP_NEEDAUTH) { 3500 /* 3501 * Remote is authenticator, but his auth proto didn't 3502 * complete yet. Defer the transition to network 3503 * phase. 3504 */ 3505 splx(x); 3506 return; 3507 } 3508 splx(x); 3509 sppp_phase_network(sp); 3510} 3511 3512static void 3513sppp_pap_tld(struct sppp *sp) 3514{ 3515 STDDCL; 3516 3517 if (debug) 3518 log(LOG_DEBUG, "%s%d: pap tld\n", ifp->if_name, ifp->if_unit); 3519 untimeout(pap.TO, (void *)sp, sp->ch[IDX_PAP]); 3520 untimeout(sppp_pap_my_TO, (void *)sp, sp->pap_my_to_ch); 3521 sp->lcp.protos &= ~(1 << IDX_PAP); 3522 3523 lcp.Close(sp); 3524} 3525 3526static void 3527sppp_pap_scr(struct sppp *sp) 3528{ 3529 STDDCL; 3530 u_char idlen, pwdlen; 3531 3532 sp->confid[IDX_PAP] = ++sp->pp_seq; 3533 pwdlen = sppp_strnlen(sp->myauth.secret, AUTHKEYLEN); 3534 idlen = sppp_strnlen(sp->myauth.name, AUTHNAMELEN); 3535 3536 sppp_auth_send(&pap, sp, PAP_REQ, sp->confid[IDX_PAP], 3537 sizeof idlen, (const char *)&idlen, 3538 (unsigned)idlen, sp->myauth.name, 3539 sizeof pwdlen, (const char *)&pwdlen, 3540 (unsigned)pwdlen, sp->myauth.secret, 3541 0); 3542} 3543/* 3544 * Random miscellaneous functions. 3545 */ 3546 3547/* 3548 * Send a PAP or CHAP proto packet. 3549 * 3550 * Varadic function, each of the elements for the ellipsis is of type 3551 * ``unsigned mlen, const u_char *msg''. Processing will stop iff 3552 * mlen == 0. 3553 */ 3554 3555static void 3556sppp_auth_send(const struct cp *cp, struct sppp *sp, u_char type, u_char id, 3557 ...) 3558{ 3559 STDDCL; 3560 struct ppp_header *h; 3561 struct lcp_header *lh; 3562 struct mbuf *m; 3563 u_char *p; 3564 int len; 3565 unsigned mlen; 3566 const char *msg; 3567 va_list ap; 3568 3569 MGETHDR (m, M_DONTWAIT, MT_DATA); 3570 if (! m) 3571 return; 3572 m->m_pkthdr.rcvif = 0; 3573 3574 h = mtod (m, struct ppp_header*); 3575 h->address = PPP_ALLSTATIONS; /* broadcast address */ 3576 h->control = PPP_UI; /* Unnumbered Info */ 3577 h->protocol = htons(cp->proto); 3578 3579 lh = (struct lcp_header*)(h + 1); 3580 lh->type = type; 3581 lh->ident = id; 3582 p = (u_char*) (lh+1); 3583 3584 va_start(ap, id); 3585 len = 0; 3586 3587 while ((mlen = va_arg(ap, unsigned)) != 0) { 3588 msg = va_arg(ap, const char *); 3589 len += mlen; 3590 if (len > MHLEN - PPP_HEADER_LEN - LCP_HEADER_LEN) { 3591 va_end(ap); 3592 m_freem(m); 3593 return; 3594 } 3595 3596 bcopy(msg, p, mlen); 3597 p += mlen; 3598 } 3599 va_end(ap); 3600 3601 m->m_pkthdr.len = m->m_len = PPP_HEADER_LEN + LCP_HEADER_LEN + len; 3602 lh->len = htons (LCP_HEADER_LEN + len); 3603 3604 if (debug) { 3605 log(LOG_DEBUG, "%s%d: %s output <%s id=0x%x len=%d", 3606 ifp->if_name, ifp->if_unit, cp->name, 3607 sppp_auth_type_name(cp->proto, lh->type), 3608 lh->ident, ntohs(lh->len)); 3609 if (len) 3610 sppp_print_bytes((u_char*) (lh+1), len); 3611 addlog(">\n"); 3612 } 3613 if (IF_QFULL (&sp->pp_cpq)) { 3614 IF_DROP (&sp->pp_fastq); 3615 IF_DROP (&ifp->if_snd); 3616 m_freem (m); 3617 ++ifp->if_oerrors; 3618 } else 3619 IF_ENQUEUE (&sp->pp_cpq, m); 3620 if (! (ifp->if_flags & IFF_OACTIVE)) 3621 (*ifp->if_start) (ifp); 3622 ifp->if_obytes += m->m_pkthdr.len + 3; 3623} 3624 3625/* 3626 * Flush interface queue. 3627 */ 3628static void 3629sppp_qflush(struct ifqueue *ifq) 3630{ 3631 struct mbuf *m, *n; 3632 3633 n = ifq->ifq_head; 3634 while ((m = n)) { 3635 n = m->m_act; 3636 m_freem (m); 3637 } 3638 ifq->ifq_head = 0; 3639 ifq->ifq_tail = 0; 3640 ifq->ifq_len = 0; 3641} 3642 3643/* 3644 * Send keepalive packets, every 10 seconds. 3645 */ 3646static void 3647sppp_keepalive(void *dummy) 3648{ 3649 struct sppp *sp; 3650 int s; 3651 3652 s = splimp(); 3653 for (sp=spppq; sp; sp=sp->pp_next) { 3654 struct ifnet *ifp = &sp->pp_if; 3655 3656 /* Keepalive mode disabled or channel down? */ 3657 if (! (sp->pp_flags & PP_KEEPALIVE) || 3658 ! (ifp->if_flags & IFF_RUNNING)) 3659 continue; 3660 3661 /* No keepalive in PPP mode if LCP not opened yet. */ 3662 if (! (sp->pp_flags & PP_CISCO) && 3663 sp->pp_phase < PHASE_AUTHENTICATE) 3664 continue; 3665 3666 if (sp->pp_alivecnt == MAXALIVECNT) { 3667 /* No keepalive packets got. Stop the interface. */ 3668 printf ("%s%d: down\n", ifp->if_name, ifp->if_unit); 3669 if_down (ifp); 3670 sppp_qflush (&sp->pp_cpq); 3671 if (! (sp->pp_flags & PP_CISCO)) { 3672 /* XXX */ 3673 /* Shut down the PPP link. */ 3674 lcp.Down(sp); 3675 /* Initiate negotiation. XXX */ 3676 lcp.Up(sp); 3677 } 3678 } 3679 if (sp->pp_alivecnt <= MAXALIVECNT) 3680 ++sp->pp_alivecnt; 3681 if (sp->pp_flags & PP_CISCO) 3682 sppp_cisco_send (sp, CISCO_KEEPALIVE_REQ, ++sp->pp_seq, 3683 sp->pp_rseq); 3684 else if (sp->pp_phase >= PHASE_AUTHENTICATE) { 3685 long nmagic = htonl (sp->lcp.magic); 3686 sp->lcp.echoid = ++sp->pp_seq; 3687 sppp_cp_send (sp, PPP_LCP, ECHO_REQ, 3688 sp->lcp.echoid, 4, &nmagic); 3689 } 3690 } 3691 splx(s); 3692 keepalive_ch = timeout(sppp_keepalive, 0, hz * 10); 3693} 3694 3695/* 3696 * Get both IP addresses. 3697 */ 3698static void 3699sppp_get_ip_addrs(struct sppp *sp, u_long *src, u_long *dst, u_long *srcmask) 3700{ 3701 struct ifnet *ifp = &sp->pp_if; 3702 struct ifaddr *ifa; 3703 struct sockaddr_in *si, *sm; 3704 u_long ssrc, ddst; 3705 3706 ssrc = ddst = 0L; 3707 /* 3708 * Pick the first AF_INET address from the list, 3709 * aliases don't make any sense on a p2p link anyway. 3710 */ 3711 for (ifa = ifp->if_addrhead.tqh_first, si = 0; 3712 ifa; 3713 ifa = ifa->ifa_link.tqe_next) 3714 if (ifa->ifa_addr->sa_family == AF_INET) { 3715 si = (struct sockaddr_in *)ifa->ifa_addr; 3716 sm = (struct sockaddr_in *)ifa->ifa_netmask; 3717 if (si) 3718 break; 3719 } 3720 if (ifa) { 3721 if (si && si->sin_addr.s_addr) { 3722 ssrc = si->sin_addr.s_addr; 3723 if (srcmask) 3724 *srcmask = ntohl(sm->sin_addr.s_addr); 3725 } 3726 3727 si = (struct sockaddr_in *)ifa->ifa_dstaddr; 3728 if (si && si->sin_addr.s_addr) 3729 ddst = si->sin_addr.s_addr; 3730 } 3731 3732 if (dst) *dst = ntohl(ddst); 3733 if (src) *src = ntohl(ssrc); 3734} 3735 3736/* 3737 * Set my IP address. Must be called at splimp. 3738 */ 3739static void 3740sppp_set_ip_addr(struct sppp *sp, u_long src) 3741{ 3742 struct ifnet *ifp = &sp->pp_if; 3743 struct ifaddr *ifa; 3744 struct sockaddr_in *si; 3745 u_long ssrc, ddst; 3746 3747 /* 3748 * Pick the first AF_INET address from the list, 3749 * aliases don't make any sense on a p2p link anyway. 3750 */ 3751 for (ifa = ifp->if_addrhead.tqh_first, si = 0; 3752 ifa; 3753 ifa = ifa->ifa_link.tqe_next) 3754 if (ifa->ifa_addr->sa_family == AF_INET) { 3755 si = (struct sockaddr_in *)ifa->ifa_addr; 3756 if (si) 3757 break; 3758 } 3759 if (ifa && si) 3760 si->sin_addr.s_addr = htonl(src); 3761} 3762 3763static int 3764sppp_params(struct sppp *sp, int cmd, void *data) 3765{ 3766 int subcmd; 3767 struct ifreq *ifr = (struct ifreq *)data; 3768 struct spppreq spr; 3769 3770 /* 3771 * ifr->ifr_data is supposed to point to a struct spppreq. 3772 * Check the cmd word first before attempting to fetch all the 3773 * data. 3774 */ 3775 if ((subcmd = fuword(ifr->ifr_data)) == -1) 3776 return EFAULT; 3777 3778 if (copyin((caddr_t)ifr->ifr_data, &spr, sizeof spr) != 0) 3779 return EFAULT; 3780 3781 switch (subcmd) { 3782 case SPPPIOGDEFS: 3783 if (cmd != SIOCGIFGENERIC) 3784 return EINVAL; 3785 /* 3786 * We copy over the entire current state, but clean 3787 * out some of the stuff we don't wanna pass up. 3788 * Remember, SIOCGIFGENERIC is unprotected, and can be 3789 * called by any user. No need to ever get PAP or 3790 * CHAP secrets back to userland anyway. 3791 */ 3792 bcopy(sp, &spr.defs, sizeof(struct sppp)); 3793 bzero(spr.defs.myauth.secret, AUTHKEYLEN); 3794 bzero(spr.defs.myauth.challenge, AUTHKEYLEN); 3795 bzero(spr.defs.hisauth.secret, AUTHKEYLEN); 3796 bzero(spr.defs.hisauth.challenge, AUTHKEYLEN); 3797 return copyout(&spr, (caddr_t)ifr->ifr_data, sizeof spr); 3798 3799 case SPPPIOSDEFS: 3800 if (cmd != SIOCSIFGENERIC) 3801 return EINVAL; 3802 /* 3803 * We have a very specific idea of which fields we allow 3804 * being passed back from userland, so to not clobber our 3805 * current state. For one, we only allow setting 3806 * anything if LCP is in dead phase. Once the LCP 3807 * negotiations started, the authentication settings must 3808 * not be changed again. (The administrator can force an 3809 * ifconfig down in order to get LCP back into dead 3810 * phase.) 3811 * 3812 * Also, we only allow for authentication parameters to be 3813 * specified. 3814 * 3815 * XXX Should allow to set or clear pp_flags. 3816 * 3817 * Finally, if the respective authentication protocol to 3818 * be used is set differently than 0, but the secret is 3819 * passed as all zeros, we don't trash the existing secret. 3820 * This allows an administrator to change the system name 3821 * only without clobbering the secret (which he didn't get 3822 * back in a previous SPPPIOGDEFS call). However, the 3823 * secrets are cleared if the authentication protocol is 3824 * reset to 0. 3825 */ 3826 if (sp->pp_phase != PHASE_DEAD) 3827 return EBUSY; 3828 3829 if ((spr.defs.myauth.proto != 0 && spr.defs.myauth.proto != PPP_PAP && 3830 spr.defs.myauth.proto != PPP_CHAP) || 3831 (spr.defs.hisauth.proto != 0 && spr.defs.hisauth.proto != PPP_PAP && 3832 spr.defs.hisauth.proto != PPP_CHAP)) 3833 return EINVAL; 3834 3835 if (spr.defs.myauth.proto == 0) 3836 /* resetting myauth */ 3837 bzero(&sp->myauth, sizeof sp->myauth); 3838 else { 3839 /* setting/changing myauth */ 3840 sp->myauth.proto = spr.defs.myauth.proto; 3841 bcopy(spr.defs.myauth.name, sp->myauth.name, AUTHNAMELEN); 3842 if (spr.defs.myauth.secret[0] != '\0') 3843 bcopy(spr.defs.myauth.secret, sp->myauth.secret, 3844 AUTHKEYLEN); 3845 } 3846 if (spr.defs.hisauth.proto == 0) 3847 /* resetting hisauth */ 3848 bzero(&sp->hisauth, sizeof sp->hisauth); 3849 else { 3850 /* setting/changing hisauth */ 3851 sp->hisauth.proto = spr.defs.hisauth.proto; 3852 sp->hisauth.flags = spr.defs.hisauth.flags; 3853 bcopy(spr.defs.hisauth.name, sp->hisauth.name, AUTHNAMELEN); 3854 if (spr.defs.hisauth.secret[0] != '\0') 3855 bcopy(spr.defs.hisauth.secret, sp->hisauth.secret, 3856 AUTHKEYLEN); 3857 } 3858 break; 3859 3860 default: 3861 return EINVAL; 3862 } 3863 3864 return 0; 3865} 3866 3867static void 3868sppp_phase_network(struct sppp *sp) 3869{ 3870 struct ifnet *ifp = &sp->pp_if; 3871 int i; 3872 u_long mask; 3873 3874 sp->pp_phase = PHASE_NETWORK; 3875 3876 log(LOG_INFO, "%s%d: phase %s\n", ifp->if_name, ifp->if_unit, 3877 sppp_phase_name(sp->pp_phase)); 3878 3879 /* Notify NCPs now. */ 3880 for (i = 0; i < IDX_COUNT; i++) 3881 if ((cps[i])->flags & CP_NCP) 3882 (cps[i])->Open(sp); 3883 3884 /* Send Up events to all NCPs. */ 3885 for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1) 3886 if (sp->lcp.protos & mask && ((cps[i])->flags & CP_NCP)) 3887 (cps[i])->Up(sp); 3888 3889 /* if no NCP is starting, all this was in vain, close down */ 3890 sppp_lcp_check_and_close(sp); 3891} 3892 3893 3894static const char * 3895sppp_cp_type_name(u_char type) 3896{ 3897 static char buf[12]; 3898 switch (type) { 3899 case CONF_REQ: return "conf-req"; 3900 case CONF_ACK: return "conf-ack"; 3901 case CONF_NAK: return "conf-nak"; 3902 case CONF_REJ: return "conf-rej"; 3903 case TERM_REQ: return "term-req"; 3904 case TERM_ACK: return "term-ack"; 3905 case CODE_REJ: return "code-rej"; 3906 case PROTO_REJ: return "proto-rej"; 3907 case ECHO_REQ: return "echo-req"; 3908 case ECHO_REPLY: return "echo-reply"; 3909 case DISC_REQ: return "discard-req"; 3910 } 3911 sprintf (buf, "0x%x", type); 3912 return buf; 3913} 3914 3915static const char * 3916sppp_auth_type_name(u_short proto, u_char type) 3917{ 3918 static char buf[12]; 3919 switch (proto) { 3920 case PPP_CHAP: 3921 switch (type) { 3922 case CHAP_CHALLENGE: return "challenge"; 3923 case CHAP_RESPONSE: return "response"; 3924 case CHAP_SUCCESS: return "success"; 3925 case CHAP_FAILURE: return "failure"; 3926 } 3927 case PPP_PAP: 3928 switch (type) { 3929 case PAP_REQ: return "req"; 3930 case PAP_ACK: return "ack"; 3931 case PAP_NAK: return "nak"; 3932 } 3933 } 3934 sprintf (buf, "0x%x", type); 3935 return buf; 3936} 3937 3938static const char * 3939sppp_lcp_opt_name(u_char opt) 3940{ 3941 static char buf[12]; 3942 switch (opt) { 3943 case LCP_OPT_MRU: return "mru"; 3944 case LCP_OPT_ASYNC_MAP: return "async-map"; 3945 case LCP_OPT_AUTH_PROTO: return "auth-proto"; 3946 case LCP_OPT_QUAL_PROTO: return "qual-proto"; 3947 case LCP_OPT_MAGIC: return "magic"; 3948 case LCP_OPT_PROTO_COMP: return "proto-comp"; 3949 case LCP_OPT_ADDR_COMP: return "addr-comp"; 3950 } 3951 sprintf (buf, "0x%x", opt); 3952 return buf; 3953} 3954 3955static const char * 3956sppp_ipcp_opt_name(u_char opt) 3957{ 3958 static char buf[12]; 3959 switch (opt) { 3960 case IPCP_OPT_ADDRESSES: return "addresses"; 3961 case IPCP_OPT_COMPRESSION: return "compression"; 3962 case IPCP_OPT_ADDRESS: return "address"; 3963 } 3964 sprintf (buf, "0x%x", opt); 3965 return buf; 3966} 3967 3968static const char * 3969sppp_state_name(int state) 3970{ 3971 switch (state) { 3972 case STATE_INITIAL: return "initial"; 3973 case STATE_STARTING: return "starting"; 3974 case STATE_CLOSED: return "closed"; 3975 case STATE_STOPPED: return "stopped"; 3976 case STATE_CLOSING: return "closing"; 3977 case STATE_STOPPING: return "stopping"; 3978 case STATE_REQ_SENT: return "req-sent"; 3979 case STATE_ACK_RCVD: return "ack-rcvd"; 3980 case STATE_ACK_SENT: return "ack-sent"; 3981 case STATE_OPENED: return "opened"; 3982 } 3983 return "illegal"; 3984} 3985 3986static const char * 3987sppp_phase_name(enum ppp_phase phase) 3988{ 3989 switch (phase) { 3990 case PHASE_DEAD: return "dead"; 3991 case PHASE_ESTABLISH: return "establish"; 3992 case PHASE_TERMINATE: return "terminate"; 3993 case PHASE_AUTHENTICATE: return "authenticate"; 3994 case PHASE_NETWORK: return "network"; 3995 } 3996 return "illegal"; 3997} 3998 3999static const char * 4000sppp_proto_name(u_short proto) 4001{ 4002 static char buf[12]; 4003 switch (proto) { 4004 case PPP_LCP: return "lcp"; 4005 case PPP_IPCP: return "ipcp"; 4006 case PPP_PAP: return "pap"; 4007 case PPP_CHAP: return "chap"; 4008 } 4009 sprintf(buf, "0x%x", (unsigned)proto); 4010 return buf; 4011} 4012 4013static void 4014sppp_print_bytes(const u_char *p, u_short len) 4015{ 4016 addlog(" %x", *p++); 4017 while (--len > 0) 4018 addlog("-%x", *p++); 4019} 4020 4021static void 4022sppp_print_string(const char *p, u_short len) 4023{ 4024 u_char c; 4025 4026 while (len-- > 0) { 4027 c = *p++; 4028 /* 4029 * Print only ASCII chars directly. RFC 1994 recommends 4030 * using only them, but we don't rely on it. */ 4031 if (c < ' ' || c > '~') 4032 addlog("\\x%x", c); 4033 else 4034 addlog("%c", c); 4035 } 4036} 4037 4038static const char * 4039sppp_dotted_quad(u_long addr) 4040{ 4041 static char s[16]; 4042 sprintf(s, "%d.%d.%d.%d", 4043 (addr >> 24) & 0xff, 4044 (addr >> 16) & 0xff, 4045 (addr >> 8) & 0xff, 4046 addr & 0xff); 4047 return s; 4048} 4049 4050static int 4051sppp_strnlen(u_char *p, int max) 4052{ 4053 int len; 4054 4055 for (len = 0; len < max && *p; ++p) 4056 ++len; 4057 return len; 4058} 4059 4060/* a dummy, used to drop uninteresting events */ 4061static void 4062sppp_null(struct sppp *unused) 4063{ 4064 /* do just nothing */ 4065} 4066/* 4067 * This file is large. Tell emacs to highlight it nevertheless. 4068 * 4069 * Local Variables: 4070 * hilit-auto-highlight-maxout: 120000 4071 * End: 4072 */ 4073