fsm.c revision 71658
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 * $FreeBSD: head/usr.sbin/ppp/fsm.c 71658 2001-01-26 01:43:38Z brian $ 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 61static void FsmSendConfigReq(struct fsm *); 62static void FsmSendTerminateReq(struct fsm *); 63static void FsmInitRestartCounter(struct fsm *, int); 64 65typedef void (recvfn)(struct fsm *, struct fsmheader *, struct mbuf *); 66static recvfn FsmRecvConfigReq, FsmRecvConfigAck, FsmRecvConfigNak, 67 FsmRecvConfigRej, FsmRecvTermReq, FsmRecvTermAck, 68 FsmRecvCodeRej, FsmRecvProtoRej, FsmRecvEchoReq, 69 FsmRecvEchoRep, FsmRecvDiscReq, FsmRecvIdent, 70 FsmRecvTimeRemain, FsmRecvResetReq, FsmRecvResetAck; 71 72static 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, 1, "Ident" }, 90 { FsmRecvTimeRemain,0, 0, "TimeRemain" }, 91 { FsmRecvResetReq, 0, 0, "ResetReq" }, 92 { FsmRecvResetAck, 0, 1, "ResetAck" } 93}; 94 95static const char * 96Code2Nam(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 103const char * 104State2Nam(u_int state) 105{ 106 static const char * const 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 116static void 117StoppedTimeout(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 131void 132fsm_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 * const 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 158static void 159NewState(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 177void 178fsm_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 = m_get(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, LINK_QUEUES(fp->link) - 1, 210 fp->proto); 211 212 if (code == CODE_CONFIGREJ) 213 lcp_SendIdentification(&fp->link->lcp); 214} 215 216static void 217FsmOpenNow(void *v) 218{ 219 struct fsm *fp = (struct fsm *)v; 220 221 timer_Stop(&fp->OpenTimer); 222 if (fp->state <= ST_STOPPED) { 223 if (fp->state != ST_STARTING) { 224 /* 225 * In practice, we're only here in ST_STOPPED (when delaying the 226 * first config request) or ST_CLOSED (when openmode == 0). 227 * 228 * The ST_STOPPED bit is breaking the RFC already :-( 229 * 230 * According to the RFC (1661) state transition table, a TLS isn't 231 * required for an Open event when state == Closed, but the RFC 232 * must be wrong as TLS hasn't yet been called (since the last TLF) 233 * ie, Initial gets an `Up' event, Closing gets a RTA etc. 234 */ 235 (*fp->fn->LayerStart)(fp); 236 (*fp->parent->LayerStart)(fp->parent->object, fp); 237 } 238 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 239 FsmSendConfigReq(fp); 240 NewState(fp, ST_REQSENT); 241 } 242} 243 244void 245fsm_Open(struct fsm *fp) 246{ 247 switch (fp->state) { 248 case ST_INITIAL: 249 NewState(fp, ST_STARTING); 250 (*fp->fn->LayerStart)(fp); 251 (*fp->parent->LayerStart)(fp->parent->object, fp); 252 break; 253 case ST_CLOSED: 254 if (fp->open_mode == OPEN_PASSIVE) { 255 NewState(fp, ST_STOPPED); /* XXX: This is a hack ! */ 256 } else if (fp->open_mode > 0) { 257 if (fp->open_mode > 1) 258 log_Printf(LogPHASE, "%s: Entering STOPPED state for %d seconds\n", 259 fp->link->name, fp->open_mode); 260 NewState(fp, ST_STOPPED); /* XXX: This is a not-so-bad hack ! */ 261 timer_Stop(&fp->OpenTimer); 262 fp->OpenTimer.load = fp->open_mode * SECTICKS; 263 fp->OpenTimer.func = FsmOpenNow; 264 fp->OpenTimer.arg = (void *)fp; 265 timer_Start(&fp->OpenTimer); 266 } else 267 FsmOpenNow(fp); 268 break; 269 case ST_STOPPED: /* XXX: restart option */ 270 case ST_REQSENT: 271 case ST_ACKRCVD: 272 case ST_ACKSENT: 273 case ST_OPENED: /* XXX: restart option */ 274 break; 275 case ST_CLOSING: /* XXX: restart option */ 276 case ST_STOPPING: /* XXX: restart option */ 277 NewState(fp, ST_STOPPING); 278 break; 279 } 280} 281 282void 283fsm_Up(struct fsm *fp) 284{ 285 switch (fp->state) { 286 case ST_INITIAL: 287 log_Printf(fp->LogLevel, "FSM: Using \"%s\" as a transport\n", 288 fp->link->name); 289 NewState(fp, ST_CLOSED); 290 break; 291 case ST_STARTING: 292 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 293 FsmSendConfigReq(fp); 294 NewState(fp, ST_REQSENT); 295 break; 296 default: 297 log_Printf(fp->LogLevel, "%s: Oops, Up at %s\n", 298 fp->link->name, State2Nam(fp->state)); 299 break; 300 } 301} 302 303void 304fsm_Down(struct fsm *fp) 305{ 306 switch (fp->state) { 307 case ST_CLOSED: 308 NewState(fp, ST_INITIAL); 309 break; 310 case ST_CLOSING: 311 /* This TLF contradicts the RFC (1661), which ``misses it out'' ! */ 312 (*fp->fn->LayerFinish)(fp); 313 NewState(fp, ST_INITIAL); 314 (*fp->parent->LayerFinish)(fp->parent->object, fp); 315 break; 316 case ST_STOPPED: 317 NewState(fp, ST_STARTING); 318 (*fp->fn->LayerStart)(fp); 319 (*fp->parent->LayerStart)(fp->parent->object, fp); 320 break; 321 case ST_STOPPING: 322 case ST_REQSENT: 323 case ST_ACKRCVD: 324 case ST_ACKSENT: 325 NewState(fp, ST_STARTING); 326 break; 327 case ST_OPENED: 328 (*fp->fn->LayerDown)(fp); 329 NewState(fp, ST_STARTING); 330 (*fp->parent->LayerDown)(fp->parent->object, fp); 331 break; 332 } 333} 334 335void 336fsm_Close(struct fsm *fp) 337{ 338 switch (fp->state) { 339 case ST_STARTING: 340 (*fp->fn->LayerFinish)(fp); 341 NewState(fp, ST_INITIAL); 342 (*fp->parent->LayerFinish)(fp->parent->object, fp); 343 break; 344 case ST_STOPPED: 345 NewState(fp, ST_CLOSED); 346 break; 347 case ST_STOPPING: 348 NewState(fp, ST_CLOSING); 349 break; 350 case ST_OPENED: 351 (*fp->fn->LayerDown)(fp); 352 if (fp->state == ST_OPENED) { 353 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 354 FsmSendTerminateReq(fp); 355 NewState(fp, ST_CLOSING); 356 (*fp->parent->LayerDown)(fp->parent->object, fp); 357 } 358 break; 359 case ST_REQSENT: 360 case ST_ACKRCVD: 361 case ST_ACKSENT: 362 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 363 FsmSendTerminateReq(fp); 364 NewState(fp, ST_CLOSING); 365 break; 366 } 367} 368 369/* 370 * Send functions 371 */ 372static void 373FsmSendConfigReq(struct fsm *fp) 374{ 375 if (fp->more.reqs-- > 0 && fp->restart-- > 0) { 376 (*fp->fn->SendConfigReq)(fp); 377 timer_Start(&fp->FsmTimer); /* Start restart timer */ 378 } else { 379 if (fp->more.reqs < 0) 380 log_Printf(LogPHASE, "%s: Too many %s REQs sent - abandoning " 381 "negotiation\n", fp->link->name, fp->name); 382 lcp_SendIdentification(&fp->link->lcp); 383 fsm_Close(fp); 384 } 385} 386 387static void 388FsmSendTerminateReq(struct fsm *fp) 389{ 390 fsm_Output(fp, CODE_TERMREQ, fp->reqid, NULL, 0, MB_UNKNOWN); 391 (*fp->fn->SentTerminateReq)(fp); 392 timer_Start(&fp->FsmTimer); /* Start restart timer */ 393 fp->restart--; /* Decrement restart counter */ 394} 395 396/* 397 * Timeout actions 398 */ 399static void 400FsmTimeout(void *v) 401{ 402 struct fsm *fp = (struct fsm *)v; 403 404 if (fp->restart) { 405 switch (fp->state) { 406 case ST_CLOSING: 407 case ST_STOPPING: 408 FsmSendTerminateReq(fp); 409 break; 410 case ST_REQSENT: 411 case ST_ACKSENT: 412 FsmSendConfigReq(fp); 413 break; 414 case ST_ACKRCVD: 415 FsmSendConfigReq(fp); 416 NewState(fp, ST_REQSENT); 417 break; 418 } 419 timer_Start(&fp->FsmTimer); 420 } else { 421 switch (fp->state) { 422 case ST_CLOSING: 423 (*fp->fn->LayerFinish)(fp); 424 NewState(fp, ST_CLOSED); 425 (*fp->parent->LayerFinish)(fp->parent->object, fp); 426 break; 427 case ST_STOPPING: 428 (*fp->fn->LayerFinish)(fp); 429 NewState(fp, ST_STOPPED); 430 (*fp->parent->LayerFinish)(fp->parent->object, fp); 431 break; 432 case ST_REQSENT: /* XXX: 3p */ 433 case ST_ACKSENT: 434 case ST_ACKRCVD: 435 (*fp->fn->LayerFinish)(fp); 436 NewState(fp, ST_STOPPED); 437 (*fp->parent->LayerFinish)(fp->parent->object, fp); 438 break; 439 } 440 } 441} 442 443static void 444FsmInitRestartCounter(struct fsm *fp, int what) 445{ 446 timer_Stop(&fp->FsmTimer); 447 fp->FsmTimer.func = FsmTimeout; 448 fp->FsmTimer.arg = (void *)fp; 449 (*fp->fn->InitRestartCounter)(fp, what); 450} 451 452/* 453 * Actions when receive packets 454 */ 455static void 456FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 457/* RCR */ 458{ 459 struct fsm_decode dec; 460 int plen, flen; 461 int ackaction = 0; 462 463 plen = m_length(bp); 464 flen = ntohs(lhp->length) - sizeof *lhp; 465 if (plen < flen) { 466 log_Printf(LogWARN, "%s: FsmRecvConfigReq: plen (%d) < flen (%d)\n", 467 fp->link->name, plen, flen); 468 m_freem(bp); 469 return; 470 } 471 472 /* Check and process easy case */ 473 switch (fp->state) { 474 case ST_INITIAL: 475 if (fp->proto == PROTO_CCP && fp->link->lcp.fsm.state == ST_OPENED) { 476 /* 477 * ccp_SetOpenMode() leaves us in initial if we're disabling 478 * & denying everything. 479 */ 480 bp = m_prepend(bp, lhp, sizeof *lhp, 2); 481 bp = proto_Prepend(bp, fp->proto, 0, 0); 482 bp = m_pullup(bp); 483 lcp_SendProtoRej(&fp->link->lcp, MBUF_CTOP(bp), bp->m_len); 484 m_freem(bp); 485 return; 486 } 487 /* Drop through */ 488 case ST_STARTING: 489 log_Printf(fp->LogLevel, "%s: Oops, RCR in %s.\n", 490 fp->link->name, State2Nam(fp->state)); 491 m_freem(bp); 492 return; 493 case ST_CLOSED: 494 (*fp->fn->SendTerminateAck)(fp, lhp->id); 495 m_freem(bp); 496 return; 497 case ST_CLOSING: 498 log_Printf(fp->LogLevel, "%s: Error: Got ConfigReq while state = %s\n", 499 fp->link->name, State2Nam(fp->state)); 500 case ST_STOPPING: 501 m_freem(bp); 502 return; 503 case ST_OPENED: 504 (*fp->fn->LayerDown)(fp); 505 (*fp->parent->LayerDown)(fp->parent->object, fp); 506 break; 507 } 508 509 bp = m_pullup(bp); 510 dec.ackend = dec.ack; 511 dec.nakend = dec.nak; 512 dec.rejend = dec.rej; 513 (*fp->fn->DecodeConfig)(fp, MBUF_CTOP(bp), flen, MODE_REQ, &dec); 514 if (flen < sizeof(struct fsmconfig)) 515 log_Printf(fp->LogLevel, " [EMPTY]\n"); 516 517 if (dec.nakend == dec.nak && dec.rejend == dec.rej) 518 ackaction = 1; 519 520 switch (fp->state) { 521 case ST_STOPPED: 522 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 523 /* Fall through */ 524 525 case ST_OPENED: 526 FsmSendConfigReq(fp); 527 break; 528 } 529 530 if (dec.rejend != dec.rej) 531 fsm_Output(fp, CODE_CONFIGREJ, lhp->id, dec.rej, dec.rejend - dec.rej, 532 MB_UNKNOWN); 533 if (dec.nakend != dec.nak) 534 fsm_Output(fp, CODE_CONFIGNAK, lhp->id, dec.nak, dec.nakend - dec.nak, 535 MB_UNKNOWN); 536 if (ackaction) 537 fsm_Output(fp, CODE_CONFIGACK, lhp->id, dec.ack, dec.ackend - dec.ack, 538 MB_UNKNOWN); 539 540 switch (fp->state) { 541 case ST_STOPPED: 542 /* 543 * According to the RFC (1661) state transition table, a TLS isn't 544 * required for a RCR when state == ST_STOPPED, but the RFC 545 * must be wrong as TLS hasn't yet been called (since the last TLF) 546 */ 547 (*fp->fn->LayerStart)(fp); 548 (*fp->parent->LayerStart)(fp->parent->object, fp); 549 /* Fall through */ 550 551 case ST_OPENED: 552 if (ackaction) 553 NewState(fp, ST_ACKSENT); 554 else 555 NewState(fp, ST_REQSENT); 556 break; 557 case ST_REQSENT: 558 if (ackaction) 559 NewState(fp, ST_ACKSENT); 560 break; 561 case ST_ACKRCVD: 562 if (ackaction) { 563 NewState(fp, ST_OPENED); 564 if ((*fp->fn->LayerUp)(fp)) 565 (*fp->parent->LayerUp)(fp->parent->object, fp); 566 else { 567 (*fp->fn->LayerDown)(fp); 568 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 569 FsmSendTerminateReq(fp); 570 NewState(fp, ST_CLOSING); 571 lcp_SendIdentification(&fp->link->lcp); 572 } 573 } 574 break; 575 case ST_ACKSENT: 576 if (!ackaction) 577 NewState(fp, ST_REQSENT); 578 break; 579 } 580 m_freem(bp); 581 582 if (dec.rejend != dec.rej && --fp->more.rejs <= 0) { 583 log_Printf(LogPHASE, "%s: Too many %s REJs sent - abandoning negotiation\n", 584 fp->link->name, fp->name); 585 lcp_SendIdentification(&fp->link->lcp); 586 fsm_Close(fp); 587 } 588 589 if (dec.nakend != dec.nak && --fp->more.naks <= 0) { 590 log_Printf(LogPHASE, "%s: Too many %s NAKs sent - abandoning negotiation\n", 591 fp->link->name, fp->name); 592 lcp_SendIdentification(&fp->link->lcp); 593 fsm_Close(fp); 594 } 595} 596 597static void 598FsmRecvConfigAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 599/* RCA */ 600{ 601 switch (fp->state) { 602 case ST_CLOSED: 603 case ST_STOPPED: 604 (*fp->fn->SendTerminateAck)(fp, lhp->id); 605 break; 606 case ST_CLOSING: 607 case ST_STOPPING: 608 break; 609 case ST_REQSENT: 610 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 611 NewState(fp, ST_ACKRCVD); 612 break; 613 case ST_ACKRCVD: 614 FsmSendConfigReq(fp); 615 NewState(fp, ST_REQSENT); 616 break; 617 case ST_ACKSENT: 618 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 619 NewState(fp, ST_OPENED); 620 if ((*fp->fn->LayerUp)(fp)) 621 (*fp->parent->LayerUp)(fp->parent->object, fp); 622 else { 623 (*fp->fn->LayerDown)(fp); 624 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 625 FsmSendTerminateReq(fp); 626 NewState(fp, ST_CLOSING); 627 lcp_SendIdentification(&fp->link->lcp); 628 } 629 break; 630 case ST_OPENED: 631 (*fp->fn->LayerDown)(fp); 632 FsmSendConfigReq(fp); 633 NewState(fp, ST_REQSENT); 634 (*fp->parent->LayerDown)(fp->parent->object, fp); 635 break; 636 } 637 m_freem(bp); 638} 639 640static void 641FsmRecvConfigNak(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 642/* RCN */ 643{ 644 struct fsm_decode dec; 645 int plen, flen; 646 647 plen = m_length(bp); 648 flen = ntohs(lhp->length) - sizeof *lhp; 649 if (plen < flen) { 650 m_freem(bp); 651 return; 652 } 653 654 /* 655 * Check and process easy case 656 */ 657 switch (fp->state) { 658 case ST_INITIAL: 659 case ST_STARTING: 660 log_Printf(fp->LogLevel, "%s: Oops, RCN in %s.\n", 661 fp->link->name, State2Nam(fp->state)); 662 m_freem(bp); 663 return; 664 case ST_CLOSED: 665 case ST_STOPPED: 666 (*fp->fn->SendTerminateAck)(fp, lhp->id); 667 m_freem(bp); 668 return; 669 case ST_CLOSING: 670 case ST_STOPPING: 671 m_freem(bp); 672 return; 673 } 674 675 bp = m_pullup(bp); 676 dec.ackend = dec.ack; 677 dec.nakend = dec.nak; 678 dec.rejend = dec.rej; 679 (*fp->fn->DecodeConfig)(fp, MBUF_CTOP(bp), flen, MODE_NAK, &dec); 680 if (flen < sizeof(struct fsmconfig)) 681 log_Printf(fp->LogLevel, " [EMPTY]\n"); 682 683 switch (fp->state) { 684 case ST_REQSENT: 685 case ST_ACKSENT: 686 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 687 FsmSendConfigReq(fp); 688 break; 689 case ST_OPENED: 690 (*fp->fn->LayerDown)(fp); 691 FsmSendConfigReq(fp); 692 NewState(fp, ST_REQSENT); 693 (*fp->parent->LayerDown)(fp->parent->object, fp); 694 break; 695 case ST_ACKRCVD: 696 FsmSendConfigReq(fp); 697 NewState(fp, ST_REQSENT); 698 break; 699 } 700 701 m_freem(bp); 702} 703 704static void 705FsmRecvTermReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 706/* RTR */ 707{ 708 switch (fp->state) { 709 case ST_INITIAL: 710 case ST_STARTING: 711 log_Printf(fp->LogLevel, "%s: Oops, RTR in %s\n", 712 fp->link->name, State2Nam(fp->state)); 713 break; 714 case ST_CLOSED: 715 case ST_STOPPED: 716 case ST_CLOSING: 717 case ST_STOPPING: 718 case ST_REQSENT: 719 (*fp->fn->SendTerminateAck)(fp, lhp->id); 720 break; 721 case ST_ACKRCVD: 722 case ST_ACKSENT: 723 (*fp->fn->SendTerminateAck)(fp, lhp->id); 724 NewState(fp, ST_REQSENT); 725 break; 726 case ST_OPENED: 727 (*fp->fn->LayerDown)(fp); 728 (*fp->fn->SendTerminateAck)(fp, lhp->id); 729 FsmInitRestartCounter(fp, FSM_TRM_TIMER); 730 timer_Start(&fp->FsmTimer); /* Start restart timer */ 731 fp->restart = 0; 732 NewState(fp, ST_STOPPING); 733 (*fp->parent->LayerDown)(fp->parent->object, fp); 734 /* A delayed ST_STOPPED is now scheduled */ 735 break; 736 } 737 m_freem(bp); 738} 739 740static void 741FsmRecvTermAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 742/* RTA */ 743{ 744 switch (fp->state) { 745 case ST_CLOSING: 746 (*fp->fn->LayerFinish)(fp); 747 NewState(fp, ST_CLOSED); 748 (*fp->parent->LayerFinish)(fp->parent->object, fp); 749 break; 750 case ST_STOPPING: 751 (*fp->fn->LayerFinish)(fp); 752 NewState(fp, ST_STOPPED); 753 (*fp->parent->LayerFinish)(fp->parent->object, fp); 754 break; 755 case ST_ACKRCVD: 756 NewState(fp, ST_REQSENT); 757 break; 758 case ST_OPENED: 759 (*fp->fn->LayerDown)(fp); 760 FsmSendConfigReq(fp); 761 NewState(fp, ST_REQSENT); 762 (*fp->parent->LayerDown)(fp->parent->object, fp); 763 break; 764 } 765 m_freem(bp); 766} 767 768static void 769FsmRecvConfigRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 770/* RCJ */ 771{ 772 struct fsm_decode dec; 773 int plen, flen; 774 775 plen = m_length(bp); 776 flen = ntohs(lhp->length) - sizeof *lhp; 777 if (plen < flen) { 778 m_freem(bp); 779 return; 780 } 781 782 lcp_SendIdentification(&fp->link->lcp); 783 784 /* 785 * Check and process easy case 786 */ 787 switch (fp->state) { 788 case ST_INITIAL: 789 case ST_STARTING: 790 log_Printf(fp->LogLevel, "%s: Oops, RCJ in %s.\n", 791 fp->link->name, State2Nam(fp->state)); 792 m_freem(bp); 793 return; 794 case ST_CLOSED: 795 case ST_STOPPED: 796 (*fp->fn->SendTerminateAck)(fp, lhp->id); 797 m_freem(bp); 798 return; 799 case ST_CLOSING: 800 case ST_STOPPING: 801 m_freem(bp); 802 return; 803 } 804 805 bp = m_pullup(bp); 806 dec.ackend = dec.ack; 807 dec.nakend = dec.nak; 808 dec.rejend = dec.rej; 809 (*fp->fn->DecodeConfig)(fp, MBUF_CTOP(bp), flen, MODE_REJ, &dec); 810 if (flen < sizeof(struct fsmconfig)) 811 log_Printf(fp->LogLevel, " [EMPTY]\n"); 812 813 switch (fp->state) { 814 case ST_REQSENT: 815 case ST_ACKSENT: 816 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 817 FsmSendConfigReq(fp); 818 break; 819 case ST_OPENED: 820 (*fp->fn->LayerDown)(fp); 821 FsmSendConfigReq(fp); 822 NewState(fp, ST_REQSENT); 823 (*fp->parent->LayerDown)(fp->parent->object, fp); 824 break; 825 case ST_ACKRCVD: 826 FsmSendConfigReq(fp); 827 NewState(fp, ST_REQSENT); 828 break; 829 } 830 m_freem(bp); 831} 832 833static void 834FsmRecvCodeRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 835{ 836 m_freem(bp); 837} 838 839static void 840FsmRecvProtoRej(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 841{ 842 struct physical *p = link2physical(fp->link); 843 u_short proto; 844 845 if (m_length(bp) < 2) { 846 m_freem(bp); 847 return; 848 } 849 bp = mbuf_Read(bp, &proto, 2); 850 proto = ntohs(proto); 851 log_Printf(fp->LogLevel, "%s: -- Protocol 0x%04x (%s) was rejected!\n", 852 fp->link->name, proto, hdlc_Protocol2Nam(proto)); 853 854 switch (proto) { 855 case PROTO_LQR: 856 if (p) 857 lqr_Stop(p, LQM_LQR); 858 else 859 log_Printf(LogERROR, "%s: FsmRecvProtoRej: Not a physical link !\n", 860 fp->link->name); 861 break; 862 case PROTO_CCP: 863 if (fp->proto == PROTO_LCP) { 864 fp = &fp->link->ccp.fsm; 865 /* Despite the RFC (1661), don't do an out-of-place TLF */ 866 /* (*fp->fn->LayerFinish)(fp); */ 867 switch (fp->state) { 868 case ST_CLOSED: 869 case ST_CLOSING: 870 NewState(fp, ST_CLOSED); 871 default: 872 NewState(fp, ST_STOPPED); 873 break; 874 } 875 /* See above */ 876 /* (*fp->parent->LayerFinish)(fp->parent->object, fp); */ 877 } 878 break; 879 case PROTO_IPCP: 880 if (fp->proto == PROTO_LCP) { 881 log_Printf(LogPHASE, "%s: IPCP protocol reject closes IPCP !\n", 882 fp->link->name); 883 fsm_Close(&fp->bundle->ncp.ipcp.fsm); 884 } 885 break; 886 case PROTO_MP: 887 if (fp->proto == PROTO_LCP) { 888 struct lcp *lcp = fsm2lcp(fp); 889 890 if (lcp->want_mrru && lcp->his_mrru) { 891 log_Printf(LogPHASE, "%s: MP protocol reject is fatal !\n", 892 fp->link->name); 893 fsm_Close(fp); 894 } 895 } 896 break; 897 } 898 m_freem(bp); 899} 900 901static void 902FsmRecvEchoReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 903{ 904 struct lcp *lcp = fsm2lcp(fp); 905 u_char *cp; 906 u_int32_t magic; 907 908 bp = m_pullup(bp); 909 m_settype(bp, MB_ECHOIN); 910 911 if (lcp && ntohs(lhp->length) - sizeof *lhp >= 4) { 912 cp = MBUF_CTOP(bp); 913 ua_ntohl(cp, &magic); 914 if (magic != lcp->his_magic) { 915 log_Printf(fp->LogLevel, "%s: RecvEchoReq: magic 0x%08lx is wrong," 916 " expecting 0x%08lx\n", fp->link->name, (u_long)magic, 917 (u_long)lcp->his_magic); 918 /* XXX: We should send terminate request */ 919 } 920 if (fp->state == ST_OPENED) { 921 ua_htonl(&lcp->want_magic, cp); /* local magic */ 922 fsm_Output(fp, CODE_ECHOREP, lhp->id, cp, 923 ntohs(lhp->length) - sizeof *lhp, MB_ECHOOUT); 924 } 925 } 926 m_freem(bp); 927} 928 929static void 930FsmRecvEchoRep(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 931{ 932 if (fsm2lcp(fp)) 933 bp = lqr_RecvEcho(fp, bp); 934 935 m_freem(bp); 936} 937 938static void 939FsmRecvDiscReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 940{ 941 m_freem(bp); 942} 943 944static void 945FsmRecvIdent(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 946{ 947 u_int32_t magic; 948 u_short len; 949 u_char *cp; 950 951 len = ntohs(lhp->length) - sizeof *lhp; 952 if (len >= 4) { 953 bp = m_pullup(m_append(bp, "", 1)); 954 cp = MBUF_CTOP(bp); 955 ua_ntohl(cp, &magic); 956 if (magic != fp->link->lcp.his_magic) 957 log_Printf(fp->LogLevel, "%s: RecvIdent: magic 0x%08lx is wrong," 958 " expecting 0x%08lx\n", fp->link->name, (u_long)magic, 959 (u_long)fp->link->lcp.his_magic); 960 cp[len] = '\0'; 961 lcp_RecvIdentification(&fp->link->lcp, cp + 4); 962 } 963 m_freem(bp); 964} 965 966static void 967FsmRecvTimeRemain(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 968{ 969 m_freem(bp); 970} 971 972static void 973FsmRecvResetReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 974{ 975 (*fp->fn->RecvResetReq)(fp); 976 /* 977 * All sendable compressed packets are queued in the first (lowest 978 * priority) modem output queue.... dump 'em to the priority queue 979 * so that they arrive at the peer before our ResetAck. 980 */ 981 link_SequenceQueue(fp->link); 982 fsm_Output(fp, CODE_RESETACK, lhp->id, NULL, 0, MB_CCPOUT); 983 m_freem(bp); 984} 985 986static void 987FsmRecvResetAck(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp) 988{ 989 (*fp->fn->RecvResetAck)(fp, lhp->id); 990 m_freem(bp); 991} 992 993void 994fsm_Input(struct fsm *fp, struct mbuf *bp) 995{ 996 int len; 997 struct fsmheader lh; 998 const struct fsmcodedesc *codep; 999 1000 len = m_length(bp); 1001 if (len < sizeof(struct fsmheader)) { 1002 m_freem(bp); 1003 return; 1004 } 1005 bp = mbuf_Read(bp, &lh, sizeof lh); 1006 1007 if (ntohs(lh.length) > len) { 1008 log_Printf(LogWARN, "%s: Oops: Got %d bytes but %d byte payload " 1009 "- dropped\n", fp->link->name, len, (int)ntohs(lh.length)); 1010 m_freem(bp); 1011 return; 1012 } 1013 1014 if (lh.code < fp->min_code || lh.code > fp->max_code || 1015 lh.code > sizeof FsmCodes / sizeof *FsmCodes) { 1016 /* 1017 * Use a private id. This is really a response-type packet, but we 1018 * MUST send a unique id for each REQ.... 1019 */ 1020 static u_char id; 1021 1022 bp = m_prepend(bp, &lh, sizeof lh, 0); 1023 bp = m_pullup(bp); 1024 fsm_Output(fp, CODE_CODEREJ, id++, MBUF_CTOP(bp), bp->m_len, MB_UNKNOWN); 1025 m_freem(bp); 1026 return; 1027 } 1028 1029 codep = FsmCodes + lh.code - 1; 1030 if (lh.id != fp->reqid && codep->check_reqid && 1031 Enabled(fp->bundle, OPT_IDCHECK)) { 1032 log_Printf(fp->LogLevel, "%s: Recv%s(%d), dropped (expected %d)\n", 1033 fp->link->name, codep->name, lh.id, fp->reqid); 1034 return; 1035 } 1036 1037 log_Printf(fp->LogLevel, "%s: Recv%s(%d) state = %s\n", 1038 fp->link->name, codep->name, lh.id, State2Nam(fp->state)); 1039 1040 if (codep->inc_reqid && (lh.id == fp->reqid || 1041 (!Enabled(fp->bundle, OPT_IDCHECK) && codep->check_reqid))) 1042 fp->reqid++; /* That's the end of that ``exchange''.... */ 1043 1044 (*codep->recv)(fp, &lh, bp); 1045} 1046 1047void 1048fsm_NullRecvResetReq(struct fsm *fp) 1049{ 1050 log_Printf(fp->LogLevel, "%s: Oops - received unexpected reset req\n", 1051 fp->link->name); 1052} 1053 1054void 1055fsm_NullRecvResetAck(struct fsm *fp, u_char id) 1056{ 1057 log_Printf(fp->LogLevel, "%s: Oops - received unexpected reset ack\n", 1058 fp->link->name); 1059} 1060 1061void 1062fsm_Reopen(struct fsm *fp) 1063{ 1064 if (fp->state == ST_OPENED) { 1065 (*fp->fn->LayerDown)(fp); 1066 FsmInitRestartCounter(fp, FSM_REQ_TIMER); 1067 FsmSendConfigReq(fp); 1068 NewState(fp, ST_REQSENT); 1069 (*fp->parent->LayerDown)(fp->parent->object, fp); 1070 } 1071} 1072 1073void 1074fsm2initial(struct fsm *fp) 1075{ 1076 timer_Stop(&fp->FsmTimer); 1077 timer_Stop(&fp->OpenTimer); 1078 timer_Stop(&fp->StoppedTimer); 1079 if (fp->state == ST_STOPPED) 1080 fsm_Close(fp); 1081 if (fp->state > ST_INITIAL) 1082 fsm_Down(fp); 1083 if (fp->state > ST_INITIAL) 1084 fsm_Close(fp); 1085} 1086