1 /*- 2 * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org> 3 * based on work by Toshiharu OHNO <tony-o@iij.ad.jp> 4 * Internet Initiative Japan, Inc (IIJ) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD: src/usr.sbin/ppp/fsm.c,v 1.52.2.8 2002/09/01 02:12:27 brian Exp $ 29 */ 30 31 #include <sys/param.h> 32 #include <netinet/in.h> 33 #include <netinet/in_systm.h> 34 #include <netinet/ip.h> 35 #include <sys/socket.h> 36 #include <sys/un.h> 37 38 #include <string.h> 39 #include <termios.h> 40 41 #include "layer.h" 42 #include "ua.h" 43 #include "mbuf.h" 44 #include "log.h" 45 #include "defs.h" 46 #include "timer.h" 47 #include "fsm.h" 48 #include "iplist.h" 49 #include "lqr.h" 50 #include "hdlc.h" 51 #include "throughput.h" 52 #include "slcompress.h" 53 #include "ncpaddr.h" 54 #include "ipcp.h" 55 #include "filter.h" 56 #include "descriptor.h" 57 #include "lcp.h" 58 #include "ccp.h" 59 #include "link.h" 60 #include "mp.h" 61 #ifndef NORADIUS 62 #include "radius.h" 63 #endif 64 #include "ipv6cp.h" 65 #include "ncp.h" 66 #include "bundle.h" 67 #include "async.h" 68 #include "physical.h" 69 #include "proto.h" 70 71 static void FsmSendConfigReq(struct fsm *); 72 static void FsmSendTerminateReq(struct fsm *); 73 static void FsmInitRestartCounter(struct fsm *, int); 74 75 typedef void (recvfn)(struct fsm *, struct fsmheader *, struct mbuf *); 76 static recvfn FsmRecvConfigReq, FsmRecvConfigAck, FsmRecvConfigNak, 77 FsmRecvConfigRej, FsmRecvTermReq, FsmRecvTermAck, 78 FsmRecvCodeRej, FsmRecvProtoRej, FsmRecvEchoReq, 79 FsmRecvEchoRep, FsmRecvDiscReq, FsmRecvIdent, 80 FsmRecvTimeRemain, FsmRecvResetReq, FsmRecvResetAck; 81 82 static const struct fsmcodedesc { 83 recvfn *recv; 84 unsigned check_reqid : 1; 85 unsigned inc_reqid : 1; 86 const char *name; 87 } FsmCodes[] = { 88 { FsmRecvConfigReq, 0, 0, "ConfigReq" }, 89 { FsmRecvConfigAck, 1, 1, "ConfigAck" }, 90 { FsmRecvConfigNak, 1, 1, "ConfigNak" }, 91 { FsmRecvConfigRej, 1, 1, "ConfigRej" }, 92 { FsmRecvTermReq, 0, 0, "TerminateReq" }, 93 { FsmRecvTermAck, 1, 1, "TerminateAck" }, 94 { FsmRecvCodeRej, 0, 0, "CodeRej" }, 95 { FsmRecvProtoRej, 0, 0, "ProtocolRej" }, 96 { FsmRecvEchoReq, 0, 0, "EchoRequest" }, 97 { FsmRecvEchoRep, 0, 0, "EchoReply" }, 98 { FsmRecvDiscReq, 0, 0, "DiscardReq" }, 99 { FsmRecvIdent, 0, 1, "Ident" }, 100 { FsmRecvTimeRemain,0, 0, "TimeRemain" }, 101 { FsmRecvResetReq, 0, 0, "ResetReq" }, 102 { FsmRecvResetAck, 0, 1, "ResetAck" } 103 }; 104 105 static const char * 106 Code2Nam(u_int code) 107 { 108 if (code == 0 || code > NELEM(FsmCodes)) 109 return "Unknown"; 110 return FsmCodes[code-1].name; 111 } 112 113 const char * 114 State2Nam(u_int state) 115 { 116 static const char * const StateNames[] = { 117 "Initial", "Starting", "Closed", "Stopped", "Closing", "Stopping", 118 "Req-Sent", "Ack-Rcvd", "Ack-Sent", "Opened", 119 }; 120 121 if (state >= NELEM(StateNames)) 122 return "unknown"; 123 return StateNames[state]; 124 } 125 126 static void 127 StoppedTimeout(void *v) 128 { 129 struct fsm *fp = (struct fsm *)v; 130 131 log_Printf(fp->LogLevel, "%s: Stopped timer expired\n", fp->link->name); 132 if (fp->OpenTimer.state == TIMER_RUNNING) { 133 log_Printf(LogWARN, "%s: %s: aborting open delay due to stopped timer\n", 134 fp->link->name, fp->name); 135 timer_Stop(&fp->OpenTimer); 136 } 137 if (fp->state == ST_STOPPED) 138 fsm2initial(fp); 139 } 140 141 void 142 fsm_Init(struct fsm *fp, const char *name, u_short proto, int mincode, 143 int maxcode, int LogLevel, struct bundle *bundle, 144 struct link *l, const struct fsm_parent *parent, 145 struct fsm_callbacks *fn, const char * const timer_names[3]) 146 { 147 fp->name = name; 148 fp->proto = proto; 149 fp->min_code = mincode; 150 fp->max_code = maxcode; 151 fp->state = fp->min_code > CODE_TERMACK ? ST_OPENED : ST_INITIAL; 152 fp->reqid = 1; 153 fp->restart = 1; 154 fp->more.reqs = fp->more.naks = fp->more.rejs = 3; 155 memset(&fp->FsmTimer, '\0', sizeof fp->FsmTimer); 156 memset(&fp->OpenTimer, '\0', sizeof fp->OpenTimer); 157 memset(&fp->StoppedTimer, '\0', sizeof fp->StoppedTimer); 158 fp->LogLevel = LogLevel; 159 fp->link = l; 160 fp->bundle = bundle; 161 fp->parent = parent; 162 fp->fn = fn; 163 fp->FsmTimer.name = timer_names[0]; 164 fp->OpenTimer.name = timer_names[1]; 165 fp->StoppedTimer.name = timer_names[2]; 166 } 167 168 static void 169 NewState(struct fsm *fp, int new) 170 { 171 log_Printf(fp->LogLevel, "%s: State change %s --> %s\n", 172 fp->link->name, State2Nam(fp->state), State2Nam(new)); 173 if (fp->state == ST_STOPPED && fp->StoppedTimer.state == TIMER_RUNNING) 174 timer_Stop(&fp->StoppedTimer); 175 fp->state = new; 176 if ((new >= ST_INITIAL && new <= ST_STOPPED) || (new == ST_OPENED)) { 177 timer_Stop(&fp->FsmTimer); 178 if (new == ST_STOPPED && fp->StoppedTimer.load) { 179 timer_Stop(&fp->StoppedTimer); 180 fp->StoppedTimer.func = StoppedTimeout; 181 fp->StoppedTimer.arg = (void *) fp; 182 timer_Start(&fp->StoppedTimer); 183 } 184 } 185 } 186 187 void 188 fsm_Output(struct fsm *fp, u_int code, u_int id, u_char *ptr, unsigned count, 189 int mtype) 190 { 191 int plen; 192 struct fsmheader lh; 193 struct mbuf *bp; 194 195 if (log_IsKept(fp->LogLevel)) { 196 log_Printf(fp->LogLevel, "%s: Send%s(%d) state = %s\n", 197 fp->link->name, Code2Nam(code), id, State2Nam(fp->state)); 198 switch (code) { 199 case CODE_CONFIGREQ: 200 case CODE_CONFIGACK: 201 case CODE_CONFIGREJ: 202 case CODE_CONFIGNAK: 203 (*fp->fn->DecodeConfig)(fp, ptr, ptr + count, MODE_NOP, NULL); 204 if (count < sizeof(struct fsm_opt_hdr)) 205 log_Printf(fp->LogLevel, " [EMPTY]\n"); 206 break; 207 } 208 } 209 210 plen = sizeof(struct fsmheader) + count; 211 lh.code = code; 212 lh.id = id; 213 lh.length = htons(plen); 214 bp = m_get(plen, mtype); 215 memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader)); 216 if (count) 217 memcpy(MBUF_CTOP(bp) + sizeof(struct fsmheader), ptr, count); 218 log_DumpBp(LogDEBUG, "fsm_Output", bp); 219 link_PushPacket(fp->link, bp, fp->bundle, LINK_QUEUES(fp->link) - 1, 220 fp->proto); 221 222 if (code == CODE_CONFIGREJ) 223 lcp_SendIdentification(&fp->link->lcp); 224 } 225 226 static void 227 FsmOpenNow(void *v) 228 { 229 struct fsm *fp = (struct fsm *)v; 230 231 timer_Stop(&fp->OpenTimer); 232 if (fp->state <= ST_STOPPED) { 233 if (fp->state != ST_STARTING) { 234 /* 235 * In practice, we're only here in ST_STOPPED (when delaying the 236 * first config request) or ST_CLOSED (when openmode == 0). 237 * 238 * The ST_STOPPED bit is breaking the RFC already :-( 239 * 240 * According to the RFC (1661) state transition table, a TLS isn't 241 * required for an Open event when state == Closed, but the RFC 242 * must be wrong as TLS hasn't yet been called (since the last TLF) 243 * ie, Initial gets an `Up' event, Closing gets a RTA etc. 244 */ 245 (*fp->fn->LayerStart)(fp); 246 (*fp->parent->LayerStart)(fp->parent->object, fp); 247 } 248 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 249 FsmSendConfigReq(fp); 250 NewState(fp, ST_REQSENT); 251 } 252 } 253 254 void 255 fsm_Open(struct fsm *fp) 256 { 257 switch (fp->state) { 258 case ST_INITIAL: 259 NewState(fp, ST_STARTING); 260 (*fp->fn->LayerStart)(fp); 261 (*fp->parent->LayerStart)(fp->parent->object, fp); 262 break; 263 case ST_CLOSED: 264 if (fp->open_mode == OPEN_PASSIVE) { 265 NewState(fp, ST_STOPPED); /* XXX: This is a hack ! */ 266 } else if (fp->open_mode > 0) { 267 if (fp->open_mode > 1) 268 log_Printf(LogPHASE, "%s: Entering STOPPED state for %d seconds\n", 269 fp->link->name, fp->open_mode); 270 NewState(fp, ST_STOPPED); /* XXX: This is a not-so-bad hack ! */ 271 timer_Stop(&fp->OpenTimer); 272 fp->OpenTimer.load = fp->open_mode * SECTICKS; 273 fp->OpenTimer.func = FsmOpenNow; 274 fp->OpenTimer.arg = (void *)fp; 275 timer_Start(&fp->OpenTimer); 276 } else 277 FsmOpenNow(fp); 278 break; 279 case ST_STOPPED: /* XXX: restart option */ 280 case ST_REQSENT: 281 case ST_ACKRCVD: 282 case ST_ACKSENT: 283 case ST_OPENED: /* XXX: restart option */ 284 break; 285 case ST_CLOSING: /* XXX: restart option */ 286 case ST_STOPPING: /* XXX: restart option */ 287 NewState(fp, ST_STOPPING); 288 break; 289 } 290 } 291 292 void 293 fsm_Up(struct fsm *fp) 294 { 295 switch (fp->state) { 296 case ST_INITIAL: 297 log_Printf(fp->LogLevel, "FSM: Using \"%s\" as a transport\n", 298 fp->link->name); 299 NewState(fp, ST_CLOSED); 300 break; 301 case ST_STARTING: 302 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 303 FsmSendConfigReq(fp); 304 NewState(fp, ST_REQSENT); 305 break; 306 default: 307 log_Printf(fp->LogLevel, "%s: Oops, Up at %s\n", 308 fp->link->name, State2Nam(fp->state)); 309 break; 310 } 311 } 312 313 void 314 fsm_Down(struct fsm *fp) 315 { 316 switch (fp->state) { 317 case ST_CLOSED: 318 NewState(fp, ST_INITIAL); 319 break; 320 case ST_CLOSING: 321 /* This TLF contradicts the RFC (1661), which ``misses it out'' ! */ 322 (*fp->fn->LayerFinish)(fp); 323 NewState(fp, ST_INITIAL); 324 (*fp->parent->LayerFinish)(fp->parent->object, fp); 325 break; 326 case ST_STOPPED: 327 NewState(fp, ST_STARTING); 328 (*fp->fn->LayerStart)(fp); 329 (*fp->parent->LayerStart)(fp->parent->object, fp); 330 break; 331 case ST_STOPPING: 332 case ST_REQSENT: 333 case ST_ACKRCVD: 334 case ST_ACKSENT: 335 NewState(fp, ST_STARTING); 336 break; 337 case ST_OPENED: 338 (*fp->fn->LayerDown)(fp); 339 NewState(fp, ST_STARTING); 340 (*fp->parent->LayerDown)(fp->parent->object, fp); 341 break; 342 } 343 } 344 345 void 346 fsm_Close(struct fsm *fp) 347 { 348 switch (fp->state) { 349 case ST_STARTING: 350 (*fp->fn->LayerFinish)(fp); 351 NewState(fp, ST_INITIAL); 352 (*fp->parent->LayerFinish)(fp->parent->object, fp); 353 break; 354 case ST_STOPPED: 355 NewState(fp, ST_CLOSED); 356 break; 357 case ST_STOPPING: 358 NewState(fp, ST_CLOSING); 359 break; 360 case ST_OPENED: 361 (*fp->fn->LayerDown)(fp); 362 if (fp->state == ST_OPENED) { 363 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 364 FsmSendTerminateReq(fp); 365 NewState(fp, ST_CLOSING); 366 (*fp->parent->LayerDown)(fp->parent->object, fp); 367 } 368 break; 369 case ST_REQSENT: 370 case ST_ACKRCVD: 371 case ST_ACKSENT: 372 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 373 FsmSendTerminateReq(fp); 374 NewState(fp, ST_CLOSING); 375 break; 376 } 377 } 378 379 /* 380 * Send functions 381 */ 382 static void 383 FsmSendConfigReq(struct fsm *fp) 384 { 385 if (fp->more.reqs-- > 0 && fp->restart-- > 0) { 386 (*fp->fn->SendConfigReq)(fp); 387 timer_Start(&fp->FsmTimer); /* Start restart timer */ 388 } else { 389 if (fp->more.reqs < 0) 390 log_Printf(LogPHASE, "%s: Too many %s REQs sent - abandoning " 391 "negotiation\n", fp->link->name, fp->name); 392 lcp_SendIdentification(&fp->link->lcp); 393 fsm_Close(fp); 394 } 395 } 396 397 static void 398 FsmSendTerminateReq(struct fsm *fp) 399 { 400 fsm_Output(fp, CODE_TERMREQ, fp->reqid, NULL, 0, MB_UNKNOWN); 401 (*fp->fn->SentTerminateReq)(fp); 402 timer_Start(&fp->FsmTimer); /* Start restart timer */ 403 fp->restart--; /* Decrement restart counter */ 404 } 405 406 /* 407 * Timeout actions 408 */ 409 static void 410 FsmTimeout(void *v) 411 { 412 struct fsm *fp = (struct fsm *)v; 413 414 if (fp->restart) { 415 switch (fp->state) { 416 case ST_CLOSING: 417 case ST_STOPPING: 418 FsmSendTerminateReq(fp); 419 break; 420 case ST_REQSENT: 421 case ST_ACKSENT: 422 FsmSendConfigReq(fp); 423 break; 424 case ST_ACKRCVD: 425 FsmSendConfigReq(fp); 426 NewState(fp, ST_REQSENT); 427 break; 428 } 429 timer_Start(&fp->FsmTimer); 430 } else { 431 switch (fp->state) { 432 case ST_CLOSING: 433 (*fp->fn->LayerFinish)(fp); 434 NewState(fp, ST_CLOSED); 435 (*fp->parent->LayerFinish)(fp->parent->object, fp); 436 break; 437 case ST_STOPPING: 438 (*fp->fn->LayerFinish)(fp); 439 NewState(fp, ST_STOPPED); 440 (*fp->parent->LayerFinish)(fp->parent->object, fp); 441 break; 442 case ST_REQSENT: /* XXX: 3p */ 443 case ST_ACKSENT: 444 case ST_ACKRCVD: 445 (*fp->fn->LayerFinish)(fp); 446 NewState(fp, ST_STOPPED); 447 (*fp->parent->LayerFinish)(fp->parent->object, fp); 448 break; 449 } 450 } 451 } 452 453 static void 454 FsmInitRestartCounter(struct fsm *fp, int what) 455 { 456 timer_Stop(&fp->FsmTimer); 457 fp->FsmTimer.func = FsmTimeout; 458 fp->FsmTimer.arg = (void *)fp; 459 (*fp->fn->InitRestartCounter)(fp, what); 460 } 461 462 /* 463 * Actions when receive packets 464 */ 465 static void 466 FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 467 /* RCR */ 468 { 469 struct fsm_decode dec; 470 int plen, flen; 471 int ackaction = 0; 472 u_char *cp; 473 474 bp = m_pullup(bp); 475 plen = m_length(bp); 476 flen = ntohs(lhp->length) - sizeof *lhp; 477 if (plen < flen) { 478 log_Printf(LogWARN, "%s: FsmRecvConfigReq: plen (%d) < flen (%d)\n", 479 fp->link->name, plen, flen); 480 m_freem(bp); 481 return; 482 } 483 484 /* Some things must be done before we Decode the packet */ 485 switch (fp->state) { 486 case ST_OPENED: 487 (*fp->fn->LayerDown)(fp); 488 } 489 490 dec.ackend = dec.ack; 491 dec.nakend = dec.nak; 492 dec.rejend = dec.rej; 493 cp = MBUF_CTOP(bp); 494 (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_REQ, &dec); 495 if (flen < (int)sizeof(struct fsm_opt_hdr)) 496 log_Printf(fp->LogLevel, " [EMPTY]\n"); 497 498 if (dec.nakend == dec.nak && dec.rejend == dec.rej) 499 ackaction = 1; 500 501 /* Check and process easy case */ 502 switch (fp->state) { 503 case ST_INITIAL: 504 if (fp->proto == PROTO_CCP && fp->link->lcp.fsm.state == ST_OPENED) { 505 /* 506 * ccp_SetOpenMode() leaves us in initial if we're disabling 507 * & denying everything. 508 */ 509 bp = m_prepend(bp, lhp, sizeof *lhp, 2); 510 bp = proto_Prepend(bp, fp->proto, 0, 0); 511 bp = m_pullup(bp); 512 lcp_SendProtoRej(&fp->link->lcp, MBUF_CTOP(bp), bp->m_len); 513 m_freem(bp); 514 return; 515 } 516 /* FALLTHROUGH */ 517 case ST_STARTING: 518 log_Printf(fp->LogLevel, "%s: Oops, RCR in %s.\n", 519 fp->link->name, State2Nam(fp->state)); 520 m_freem(bp); 521 return; 522 case ST_CLOSED: 523 (*fp->fn->SendTerminateAck)(fp, lhp->id); 524 m_freem(bp); 525 return; 526 case ST_CLOSING: 527 log_Printf(fp->LogLevel, "%s: Error: Got ConfigReq while state = %s\n", 528 fp->link->name, State2Nam(fp->state)); 529 /* FALLTHROUGH */ 530 case ST_STOPPING: 531 m_freem(bp); 532 return; 533 case ST_STOPPED: 534 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 535 /* FALLTHROUGH */ 536 case ST_OPENED: 537 FsmSendConfigReq(fp); 538 break; 539 } 540 541 if (dec.rejend != dec.rej) 542 fsm_Output(fp, CODE_CONFIGREJ, lhp->id, dec.rej, dec.rejend - dec.rej, 543 MB_UNKNOWN); 544 if (dec.nakend != dec.nak) 545 fsm_Output(fp, CODE_CONFIGNAK, lhp->id, dec.nak, dec.nakend - dec.nak, 546 MB_UNKNOWN); 547 if (ackaction) 548 fsm_Output(fp, CODE_CONFIGACK, lhp->id, dec.ack, dec.ackend - dec.ack, 549 MB_UNKNOWN); 550 551 switch (fp->state) { 552 case ST_STOPPED: 553 /* 554 * According to the RFC (1661) state transition table, a TLS isn't 555 * required for a RCR when state == ST_STOPPED, but the RFC 556 * must be wrong as TLS hasn't yet been called (since the last TLF) 557 */ 558 (*fp->fn->LayerStart)(fp); 559 (*fp->parent->LayerStart)(fp->parent->object, fp); 560 /* FALLTHROUGH */ 561 562 case ST_OPENED: 563 if (ackaction) 564 NewState(fp, ST_ACKSENT); 565 else 566 NewState(fp, ST_REQSENT); 567 (*fp->parent->LayerDown)(fp->parent->object, fp); 568 break; 569 case ST_REQSENT: 570 if (ackaction) 571 NewState(fp, ST_ACKSENT); 572 break; 573 case ST_ACKRCVD: 574 if (ackaction) { 575 NewState(fp, ST_OPENED); 576 if ((*fp->fn->LayerUp)(fp)) 577 (*fp->parent->LayerUp)(fp->parent->object, fp); 578 else { 579 (*fp->fn->LayerDown)(fp); 580 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 581 FsmSendTerminateReq(fp); 582 NewState(fp, ST_CLOSING); 583 lcp_SendIdentification(&fp->link->lcp); 584 } 585 } 586 break; 587 case ST_ACKSENT: 588 if (!ackaction) 589 NewState(fp, ST_REQSENT); 590 break; 591 } 592 m_freem(bp); 593 594 if (dec.rejend != dec.rej && --fp->more.rejs <= 0) { 595 log_Printf(LogPHASE, "%s: Too many %s REJs sent - abandoning negotiation\n", 596 fp->link->name, fp->name); 597 lcp_SendIdentification(&fp->link->lcp); 598 fsm_Close(fp); 599 } 600 601 if (dec.nakend != dec.nak && --fp->more.naks <= 0) { 602 log_Printf(LogPHASE, "%s: Too many %s NAKs sent - abandoning negotiation\n", 603 fp->link->name, fp->name); 604 lcp_SendIdentification(&fp->link->lcp); 605 fsm_Close(fp); 606 } 607 } 608 609 static void 610 FsmRecvConfigAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 611 /* RCA */ 612 { 613 struct fsm_decode dec; 614 int plen, flen; 615 u_char *cp; 616 617 plen = m_length(bp); 618 flen = ntohs(lhp->length) - sizeof *lhp; 619 if (plen < flen) { 620 m_freem(bp); 621 return; 622 } 623 624 bp = m_pullup(bp); 625 dec.ackend = dec.ack; 626 dec.nakend = dec.nak; 627 dec.rejend = dec.rej; 628 cp = MBUF_CTOP(bp); 629 (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_ACK, &dec); 630 if (flen < (int)sizeof(struct fsm_opt_hdr)) 631 log_Printf(fp->LogLevel, " [EMPTY]\n"); 632 633 switch (fp->state) { 634 case ST_CLOSED: 635 case ST_STOPPED: 636 (*fp->fn->SendTerminateAck)(fp, lhp->id); 637 break; 638 case ST_CLOSING: 639 case ST_STOPPING: 640 break; 641 case ST_REQSENT: 642 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 643 NewState(fp, ST_ACKRCVD); 644 break; 645 case ST_ACKRCVD: 646 FsmSendConfigReq(fp); 647 NewState(fp, ST_REQSENT); 648 break; 649 case ST_ACKSENT: 650 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 651 NewState(fp, ST_OPENED); 652 if ((*fp->fn->LayerUp)(fp)) 653 (*fp->parent->LayerUp)(fp->parent->object, fp); 654 else { 655 (*fp->fn->LayerDown)(fp); 656 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 657 FsmSendTerminateReq(fp); 658 NewState(fp, ST_CLOSING); 659 lcp_SendIdentification(&fp->link->lcp); 660 } 661 break; 662 case ST_OPENED: 663 (*fp->fn->LayerDown)(fp); 664 FsmSendConfigReq(fp); 665 NewState(fp, ST_REQSENT); 666 (*fp->parent->LayerDown)(fp->parent->object, fp); 667 break; 668 } 669 m_freem(bp); 670 } 671 672 static void 673 FsmRecvConfigNak(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 674 /* RCN */ 675 { 676 struct fsm_decode dec; 677 int plen, flen; 678 u_char *cp; 679 680 plen = m_length(bp); 681 flen = ntohs(lhp->length) - sizeof *lhp; 682 if (plen < flen) { 683 m_freem(bp); 684 return; 685 } 686 687 /* 688 * Check and process easy case 689 */ 690 switch (fp->state) { 691 case ST_INITIAL: 692 case ST_STARTING: 693 log_Printf(fp->LogLevel, "%s: Oops, RCN in %s.\n", 694 fp->link->name, State2Nam(fp->state)); 695 m_freem(bp); 696 return; 697 case ST_CLOSED: 698 case ST_STOPPED: 699 (*fp->fn->SendTerminateAck)(fp, lhp->id); 700 m_freem(bp); 701 return; 702 case ST_CLOSING: 703 case ST_STOPPING: 704 m_freem(bp); 705 return; 706 } 707 708 bp = m_pullup(bp); 709 dec.ackend = dec.ack; 710 dec.nakend = dec.nak; 711 dec.rejend = dec.rej; 712 cp = MBUF_CTOP(bp); 713 (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_NAK, &dec); 714 if (flen < (int)sizeof(struct fsm_opt_hdr)) 715 log_Printf(fp->LogLevel, " [EMPTY]\n"); 716 717 switch (fp->state) { 718 case ST_REQSENT: 719 case ST_ACKSENT: 720 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 721 FsmSendConfigReq(fp); 722 break; 723 case ST_OPENED: 724 (*fp->fn->LayerDown)(fp); 725 FsmSendConfigReq(fp); 726 NewState(fp, ST_REQSENT); 727 (*fp->parent->LayerDown)(fp->parent->object, fp); 728 break; 729 case ST_ACKRCVD: 730 FsmSendConfigReq(fp); 731 NewState(fp, ST_REQSENT); 732 break; 733 } 734 735 m_freem(bp); 736 } 737 738 static void 739 FsmRecvTermReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 740 /* RTR */ 741 { 742 switch (fp->state) { 743 case ST_INITIAL: 744 case ST_STARTING: 745 log_Printf(fp->LogLevel, "%s: Oops, RTR in %s\n", 746 fp->link->name, State2Nam(fp->state)); 747 break; 748 case ST_CLOSED: 749 case ST_STOPPED: 750 case ST_CLOSING: 751 case ST_STOPPING: 752 case ST_REQSENT: 753 (*fp->fn->SendTerminateAck)(fp, lhp->id); 754 break; 755 case ST_ACKRCVD: 756 case ST_ACKSENT: 757 (*fp->fn->SendTerminateAck)(fp, lhp->id); 758 NewState(fp, ST_REQSENT); 759 break; 760 case ST_OPENED: 761 (*fp->fn->LayerDown)(fp); 762 (*fp->fn->SendTerminateAck)(fp, lhp->id); 763 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 764 timer_Start(&fp->FsmTimer); /* Start restart timer */ 765 fp->restart = 0; 766 NewState(fp, ST_STOPPING); 767 (*fp->parent->LayerDown)(fp->parent->object, fp); 768 /* A delayed ST_STOPPED is now scheduled */ 769 break; 770 } 771 m_freem(bp); 772 } 773 774 static void 775 FsmRecvTermAck(struct fsm *fp, struct fsmheader *lhp __unused, struct mbuf *bp) 776 /* RTA */ 777 { 778 switch (fp->state) { 779 case ST_CLOSING: 780 (*fp->fn->LayerFinish)(fp); 781 NewState(fp, ST_CLOSED); 782 (*fp->parent->LayerFinish)(fp->parent->object, fp); 783 break; 784 case ST_STOPPING: 785 (*fp->fn->LayerFinish)(fp); 786 NewState(fp, ST_STOPPED); 787 (*fp->parent->LayerFinish)(fp->parent->object, fp); 788 break; 789 case ST_ACKRCVD: 790 NewState(fp, ST_REQSENT); 791 break; 792 case ST_OPENED: 793 (*fp->fn->LayerDown)(fp); 794 FsmSendConfigReq(fp); 795 NewState(fp, ST_REQSENT); 796 (*fp->parent->LayerDown)(fp->parent->object, fp); 797 break; 798 } 799 m_freem(bp); 800 } 801 802 static void 803 FsmRecvConfigRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 804 /* RCJ */ 805 { 806 struct fsm_decode dec; 807 size_t plen; 808 int flen; 809 u_char *cp; 810 811 plen = m_length(bp); 812 flen = ntohs(lhp->length) - sizeof *lhp; 813 if ((int)plen < flen) { 814 m_freem(bp); 815 return; 816 } 817 818 lcp_SendIdentification(&fp->link->lcp); 819 820 /* 821 * Check and process easy case 822 */ 823 switch (fp->state) { 824 case ST_INITIAL: 825 case ST_STARTING: 826 log_Printf(fp->LogLevel, "%s: Oops, RCJ in %s.\n", 827 fp->link->name, State2Nam(fp->state)); 828 m_freem(bp); 829 return; 830 case ST_CLOSED: 831 case ST_STOPPED: 832 (*fp->fn->SendTerminateAck)(fp, lhp->id); 833 m_freem(bp); 834 return; 835 case ST_CLOSING: 836 case ST_STOPPING: 837 m_freem(bp); 838 return; 839 } 840 841 bp = m_pullup(bp); 842 dec.ackend = dec.ack; 843 dec.nakend = dec.nak; 844 dec.rejend = dec.rej; 845 cp = MBUF_CTOP(bp); 846 (*fp->fn->DecodeConfig)(fp, cp, cp + flen, MODE_REJ, &dec); 847 if (flen < (int)sizeof(struct fsm_opt_hdr)) 848 log_Printf(fp->LogLevel, " [EMPTY]\n"); 849 850 switch (fp->state) { 851 case ST_REQSENT: 852 case ST_ACKSENT: 853 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 854 FsmSendConfigReq(fp); 855 break; 856 case ST_OPENED: 857 (*fp->fn->LayerDown)(fp); 858 FsmSendConfigReq(fp); 859 NewState(fp, ST_REQSENT); 860 (*fp->parent->LayerDown)(fp->parent->object, fp); 861 break; 862 case ST_ACKRCVD: 863 FsmSendConfigReq(fp); 864 NewState(fp, ST_REQSENT); 865 break; 866 } 867 m_freem(bp); 868 } 869 870 static void 871 FsmRecvCodeRej(struct fsm *fp __unused, struct fsmheader *lhp __unused, 872 struct mbuf *bp) 873 { 874 m_freem(bp); 875 } 876 877 static void 878 FsmRecvProtoRej(struct fsm *fp, struct fsmheader *lhp __unused, struct mbuf *bp) 879 { 880 struct physical *p = link2physical(fp->link); 881 u_short proto; 882 883 if (m_length(bp) < 2) { 884 m_freem(bp); 885 return; 886 } 887 bp = mbuf_Read(bp, &proto, 2); 888 proto = ntohs(proto); 889 log_Printf(fp->LogLevel, "%s: -- Protocol 0x%04x (%s) was rejected!\n", 890 fp->link->name, proto, hdlc_Protocol2Nam(proto)); 891 892 switch (proto) { 893 case PROTO_LQR: 894 if (p) 895 lqr_Stop(p, LQM_LQR); 896 else 897 log_Printf(LogERROR, "%s: FsmRecvProtoRej: Not a physical link !\n", 898 fp->link->name); 899 break; 900 case PROTO_CCP: 901 if (fp->proto == PROTO_LCP) { 902 fp = &fp->link->ccp.fsm; 903 /* Despite the RFC (1661), don't do an out-of-place TLF */ 904 /* (*fp->fn->LayerFinish)(fp); */ 905 switch (fp->state) { 906 case ST_CLOSED: 907 case ST_CLOSING: 908 NewState(fp, ST_CLOSED); 909 break; 910 default: 911 NewState(fp, ST_STOPPED); 912 break; 913 } 914 /* See above */ 915 /* (*fp->parent->LayerFinish)(fp->parent->object, fp); */ 916 } 917 break; 918 case PROTO_IPCP: 919 if (fp->proto == PROTO_LCP) { 920 log_Printf(LogPHASE, "%s: IPCP protocol reject closes IPCP !\n", 921 fp->link->name); 922 fsm_Close(&fp->bundle->ncp.ipcp.fsm); 923 } 924 break; 925 #ifndef NOINET6 926 case PROTO_IPV6CP: 927 if (fp->proto == PROTO_LCP) { 928 log_Printf(LogPHASE, "%s: IPV6CP protocol reject closes IPV6CP !\n", 929 fp->link->name); 930 fsm_Close(&fp->bundle->ncp.ipv6cp.fsm); 931 } 932 break; 933 #endif 934 case PROTO_MP: 935 if (fp->proto == PROTO_LCP) { 936 struct lcp *lcp = fsm2lcp(fp); 937 938 if (lcp->want_mrru && lcp->his_mrru) { 939 log_Printf(LogPHASE, "%s: MP protocol reject is fatal !\n", 940 fp->link->name); 941 fsm_Close(fp); 942 } 943 } 944 break; 945 } 946 m_freem(bp); 947 } 948 949 static void 950 FsmRecvEchoReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 951 { 952 struct lcp *lcp = fsm2lcp(fp); 953 u_char *cp; 954 u_int32_t magic; 955 956 bp = m_pullup(bp); 957 m_settype(bp, MB_ECHOIN); 958 959 if (lcp && ntohs(lhp->length) - sizeof *lhp >= 4) { 960 cp = MBUF_CTOP(bp); 961 ua_ntohl(cp, &magic); 962 if (magic != lcp->his_magic) { 963 log_Printf(fp->LogLevel, "%s: RecvEchoReq: magic 0x%08lx is wrong," 964 " expecting 0x%08lx\n", fp->link->name, (u_long)magic, 965 (u_long)lcp->his_magic); 966 /* XXX: We should send terminate request */ 967 } 968 if (fp->state == ST_OPENED) { 969 ua_htonl(&lcp->want_magic, cp); /* local magic */ 970 fsm_Output(fp, CODE_ECHOREP, lhp->id, cp, 971 ntohs(lhp->length) - sizeof *lhp, MB_ECHOOUT); 972 } 973 } 974 m_freem(bp); 975 } 976 977 static void 978 FsmRecvEchoRep(struct fsm *fp, struct fsmheader *lhp __unused, struct mbuf *bp) 979 { 980 if (fsm2lcp(fp)) 981 bp = lqr_RecvEcho(fp, bp); 982 983 m_freem(bp); 984 } 985 986 static void 987 FsmRecvDiscReq(struct fsm *fp __unused, struct fsmheader *lhp __unused, 988 struct mbuf *bp) 989 { 990 m_freem(bp); 991 } 992 993 static void 994 FsmRecvIdent(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 995 { 996 u_int32_t magic; 997 u_short len; 998 u_char *cp; 999 1000 len = ntohs(lhp->length) - sizeof *lhp; 1001 if (len >= 4) { 1002 bp = m_pullup(m_append(bp, "", 1)); 1003 cp = MBUF_CTOP(bp); 1004 ua_ntohl(cp, &magic); 1005 if (magic != fp->link->lcp.his_magic) 1006 log_Printf(fp->LogLevel, "%s: RecvIdent: magic 0x%08lx is wrong," 1007 " expecting 0x%08lx\n", fp->link->name, (u_long)magic, 1008 (u_long)fp->link->lcp.his_magic); 1009 cp[len] = '\0'; 1010 lcp_RecvIdentification(&fp->link->lcp, cp + 4); 1011 } 1012 m_freem(bp); 1013 } 1014 1015 static void 1016 FsmRecvTimeRemain(struct fsm *fp __unused, struct fsmheader *lhp __unused, 1017 struct mbuf *bp) 1018 { 1019 m_freem(bp); 1020 } 1021 1022 static void 1023 FsmRecvResetReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 1024 { 1025 if ((*fp->fn->RecvResetReq)(fp)) { 1026 /* 1027 * All sendable compressed packets are queued in the first (lowest 1028 * priority) modem output queue.... dump 'em to the priority queue 1029 * so that they arrive at the peer before our ResetAck. 1030 */ 1031 link_SequenceQueue(fp->link); 1032 fsm_Output(fp, CODE_RESETACK, lhp->id, NULL, 0, MB_CCPOUT); 1033 } 1034 m_freem(bp); 1035 } 1036 1037 static void 1038 FsmRecvResetAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 1039 { 1040 (*fp->fn->RecvResetAck)(fp, lhp->id); 1041 m_freem(bp); 1042 } 1043 1044 void 1045 fsm_Input(struct fsm *fp, struct mbuf *bp) 1046 { 1047 size_t len; 1048 struct fsmheader lh; 1049 const struct fsmcodedesc *codep; 1050 1051 len = m_length(bp); 1052 if (len < sizeof(struct fsmheader)) { 1053 m_freem(bp); 1054 return; 1055 } 1056 bp = mbuf_Read(bp, &lh, sizeof lh); 1057 1058 if (ntohs(lh.length) > len) { 1059 log_Printf(LogWARN, "%s: Oops: Got %zu bytes but %d byte payload " 1060 "- dropped\n", fp->link->name, len, (int)ntohs(lh.length)); 1061 m_freem(bp); 1062 return; 1063 } 1064 1065 if (lh.code < fp->min_code || lh.code > fp->max_code || 1066 lh.code > NELEM(FsmCodes)) { 1067 /* 1068 * Use a private id. This is really a response-type packet, but we 1069 * MUST send a unique id for each REQ.... 1070 */ 1071 static u_char id; 1072 1073 bp = m_prepend(bp, &lh, sizeof lh, 0); 1074 bp = m_pullup(bp); 1075 fsm_Output(fp, CODE_CODEREJ, id++, MBUF_CTOP(bp), bp->m_len, MB_UNKNOWN); 1076 m_freem(bp); 1077 return; 1078 } 1079 1080 codep = FsmCodes + lh.code - 1; 1081 if (lh.id != fp->reqid && codep->check_reqid && 1082 Enabled(fp->bundle, OPT_IDCHECK)) { 1083 log_Printf(fp->LogLevel, "%s: Recv%s(%d), dropped (expected %d)\n", 1084 fp->link->name, codep->name, lh.id, fp->reqid); 1085 return; 1086 } 1087 1088 log_Printf(fp->LogLevel, "%s: Recv%s(%d) state = %s\n", 1089 fp->link->name, codep->name, lh.id, State2Nam(fp->state)); 1090 1091 if (codep->inc_reqid && (lh.id == fp->reqid || 1092 (!Enabled(fp->bundle, OPT_IDCHECK) && codep->check_reqid))) 1093 fp->reqid++; /* That's the end of that ``exchange''.... */ 1094 1095 (*codep->recv)(fp, &lh, bp); 1096 } 1097 1098 int 1099 fsm_NullRecvResetReq(struct fsm *fp) 1100 { 1101 log_Printf(fp->LogLevel, "%s: Oops - received unexpected reset req\n", 1102 fp->link->name); 1103 return 1; 1104 } 1105 1106 void 1107 fsm_NullRecvResetAck(struct fsm *fp, u_char id __unused) 1108 { 1109 log_Printf(fp->LogLevel, "%s: Oops - received unexpected reset ack\n", 1110 fp->link->name); 1111 } 1112 1113 void 1114 fsm_Reopen(struct fsm *fp) 1115 { 1116 if (fp->state == ST_OPENED) { 1117 (*fp->fn->LayerDown)(fp); 1118 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 1119 FsmSendConfigReq(fp); 1120 NewState(fp, ST_REQSENT); 1121 (*fp->parent->LayerDown)(fp->parent->object, fp); 1122 } 1123 } 1124 1125 void 1126 fsm2initial(struct fsm *fp) 1127 { 1128 timer_Stop(&fp->FsmTimer); 1129 timer_Stop(&fp->OpenTimer); 1130 timer_Stop(&fp->StoppedTimer); 1131 if (fp->state == ST_STOPPED) 1132 fsm_Close(fp); 1133 if (fp->state > ST_INITIAL) 1134 fsm_Down(fp); 1135 if (fp->state > ST_INITIAL) 1136 fsm_Close(fp); 1137 } 1138 1139 struct fsm_opt * 1140 fsm_readopt(u_char **cp) 1141 { 1142 struct fsm_opt *o = (struct fsm_opt *)*cp; 1143 1144 if (o->hdr.len < sizeof(struct fsm_opt_hdr)) { 1145 log_Printf(LogERROR, "Bad option length %d (out of phase?)\n", o->hdr.len); 1146 return NULL; 1147 } 1148 1149 *cp += o->hdr.len; 1150 1151 if (o->hdr.len > sizeof(struct fsm_opt)) { 1152 log_Printf(LogERROR, "Warning: Truncating option length from %d to %d\n", 1153 o->hdr.len, (int)sizeof(struct fsm_opt)); 1154 o->hdr.len = sizeof(struct fsm_opt); 1155 } 1156 1157 return o; 1158 } 1159 1160 static int 1161 fsm_opt(u_char *opt, int optlen, const struct fsm_opt *o) 1162 { 1163 unsigned cplen = o->hdr.len; 1164 1165 if (optlen < (int)sizeof(struct fsm_opt_hdr)) 1166 optlen = 0; 1167 1168 if ((int)cplen > optlen) { 1169 log_Printf(LogERROR, "Can't REJ length %d - trunating to %d\n", 1170 cplen, optlen); 1171 cplen = optlen; 1172 } 1173 memcpy(opt, o, cplen); 1174 if (cplen) 1175 opt[1] = cplen; 1176 1177 return cplen; 1178 } 1179 1180 void 1181 fsm_rej(struct fsm_decode *dec, const struct fsm_opt *o) 1182 { 1183 if (!dec) 1184 return; 1185 dec->rejend += fsm_opt(dec->rejend, FSM_OPTLEN - (dec->rejend - dec->rej), o); 1186 } 1187 1188 void 1189 fsm_ack(struct fsm_decode *dec, const struct fsm_opt *o) 1190 { 1191 if (!dec) 1192 return; 1193 dec->ackend += fsm_opt(dec->ackend, FSM_OPTLEN - (dec->ackend - dec->ack), o); 1194 } 1195 1196 void 1197 fsm_nak(struct fsm_decode *dec, const struct fsm_opt *o) 1198 { 1199 if (!dec) 1200 return; 1201 dec->nakend += fsm_opt(dec->nakend, FSM_OPTLEN - (dec->nakend - dec->nak), o); 1202 } 1203 1204 void 1205 fsm_opt_normalise(struct fsm_decode *dec) 1206 { 1207 if (dec->rejend != dec->rej) { 1208 /* rejects are preferred */ 1209 dec->ackend = dec->ack; 1210 dec->nakend = dec->nak; 1211 } else if (dec->nakend != dec->nak) 1212 /* then NAKs */ 1213 dec->ackend = dec->ack; 1214 } 1215