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