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