1 /* Copyright (c) University of British Columbia, 1984 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/mbuf.h" 6 #include "../h/domain.h" 7 #include "../h/socket.h" 8 #include "../h/protosw.h" 9 #include "../h/errno.h" 10 #include "../h/time.h" 11 #include "../h/kernel.h" 12 13 #include "../net/if.h" 14 15 #include "../netccitt/hdlc.h" 16 #include "../netccitt/hd_var.h" 17 #include "../netccitt/x25.h" 18 19 /* 20 * HDLC INPUT INTERFACE 21 * 22 * This routine is called when the HDLC physical device has 23 * completed reading a frame. 24 */ 25 26 hdintr () 27 { 28 register struct mbuf *m; 29 register struct hdcb *hdp; 30 register struct ifnet *ifp; 31 register int s; 32 static struct ifnet *lastifp; 33 static struct hdcb *lasthdp; 34 35 for (;;) { 36 s = splimp (); 37 IF_DEQUEUEIF(&hdintrq, m, ifp); 38 splx (s); 39 if (m == 0) 40 break; 41 if (m->m_len < HDHEADERLN) { 42 printf ("hdintr: packet too short (len=%d)\n", 43 m->m_len); 44 m_freem (m); 45 continue; 46 } 47 48 /* 49 * look up the appropriate hdlc control block 50 */ 51 52 if (ifp == lastifp) 53 hdp = lasthdp; 54 else { 55 for (hdp = hdcbhead; hdp; hdp = hdp->hd_next) 56 if (hdp->hd_ifp == ifp) 57 break; 58 if (hdp == 0) { 59 printf ("hdintr: unknown interface %x\n", ifp); 60 m_freem (m); 61 continue; 62 } 63 lastifp = ifp; 64 lasthdp = hdp; 65 } 66 67 /* Process_rxframe returns FALSE if the frame was NOT queued 68 for the next higher layers. */ 69 if (process_rxframe (hdp, m) == FALSE) 70 m_freem (m); 71 } 72 } 73 74 process_rxframe (hdp, fbuf) 75 register struct hdcb *hdp; 76 register struct mbuf *fbuf; 77 { 78 register int queued = FALSE, frametype, pf; 79 register struct Hdlc_frame *frame; 80 81 frame = mtod (fbuf, struct Hdlc_frame *); 82 pf = ((struct Hdlc_iframe *) frame) -> pf; 83 84 hd_trace (hdp, RX, frame); 85 if (frame -> address != ADDRESS_A && frame -> address != ADDRESS_B) 86 return (queued); 87 88 switch ((frametype = hd_decode (hdp, frame)) + hdp->hd_state) { 89 case DM + DISC_SENT: 90 case UA + DISC_SENT: 91 /* 92 * Link now closed. Leave timer running 93 * so hd_timer() can periodically check the 94 * status of interface driver flag bit IFF_UP. 95 */ 96 hdp->hd_state = DISCONNECTED; 97 break; 98 99 case DM + INIT: 100 case UA + INIT: 101 /* 102 * This is a non-standard state change needed for DCEs 103 * that do dynamic link selection. We can't go into the 104 * usual "SEND DM" state because a DM is a SARM in LAP. 105 */ 106 hd_writeinternal (hdp, SABM, POLLOFF); 107 hdp->hd_state = SABM_SENT; 108 SET_TIMER (hdp); 109 break; 110 111 case SABM + DM_SENT: 112 case SABM + WAIT_SABM: 113 hd_writeinternal (hdp, UA, pf); 114 case UA + SABM_SENT: 115 case UA + WAIT_UA: 116 KILL_TIMER (hdp); 117 hd_initvars (hdp); 118 hdp->hd_state = ABM; 119 hd_message (hdp, "Link level operational"); 120 /* Notify the packet level - to send RESTART. */ 121 (void) pk_ctlinput (PRC_LINKUP, hdp->hd_xcp); 122 break; 123 124 case SABM + SABM_SENT: 125 /* Got a SABM collision. Acknowledge the remote's SABM 126 via UA but still wait for UA. */ 127 hd_writeinternal (hdp, UA, pf); 128 break; 129 130 case SABM + ABM: 131 /* Request to reset the link from the remote. */ 132 KILL_TIMER (hdp); 133 hd_message (hdp, "Link reset"); 134 #ifdef HDLCDEBUG 135 hd_dumptrace (hdp); 136 #endif 137 hd_flush (hdp->hd_ifp); 138 hd_writeinternal (hdp, UA, pf); 139 hd_initvars (hdp); 140 (void) pk_ctlinput (PRC_LINKRESET, hdp->hd_xcp); 141 hdp->hd_resets++; 142 break; 143 144 case SABM + WAIT_UA: 145 hd_writeinternal (hdp, UA, pf); 146 break; 147 148 case DM + ABM: 149 hd_message (hdp, "DM received: link down"); 150 #ifdef HDLCDEBUG 151 hd_dumptrace (hdp); 152 #endif 153 (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_xcp); 154 hd_flush (hdp->hd_ifp); 155 case DM + DM_SENT: 156 case DM + WAIT_SABM: 157 case DM + WAIT_UA: 158 hd_writeinternal (hdp, SABM, pf); 159 hdp->hd_state = SABM_SENT; 160 SET_TIMER (hdp); 161 break; 162 163 case DISC + INIT: 164 case DISC + DM_SENT: 165 case DISC + SABM_SENT: 166 /* Note: This is a non-standard state change. */ 167 hd_writeinternal (hdp, UA, pf); 168 hd_writeinternal (hdp, SABM, POLLOFF); 169 hdp->hd_state = SABM_SENT; 170 SET_TIMER (hdp); 171 break; 172 173 case DISC + WAIT_UA: 174 hd_writeinternal (hdp, DM, pf); 175 SET_TIMER (hdp); 176 hdp->hd_state = DM_SENT; 177 break; 178 179 case DISC + ABM: 180 hd_message (hdp, "DISC received: link down"); 181 (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_xcp); 182 case DISC + WAIT_SABM: 183 hd_writeinternal (hdp, UA, pf); 184 hdp->hd_state = DM_SENT; 185 SET_TIMER (hdp); 186 break; 187 188 case UA + ABM: 189 hd_message (hdp, "UA received: link down"); 190 (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_xcp); 191 case UA + WAIT_SABM: 192 hd_writeinternal (hdp, DM, pf); 193 hdp->hd_state = DM_SENT; 194 SET_TIMER (hdp); 195 break; 196 197 case FRMR + DM_SENT: 198 hd_writeinternal (hdp, SABM, pf); 199 hdp->hd_state = SABM_SENT; 200 SET_TIMER (hdp); 201 break; 202 203 case FRMR + WAIT_SABM: 204 hd_writeinternal (hdp, DM, pf); 205 hdp->hd_state = DM_SENT; 206 SET_TIMER (hdp); 207 break; 208 209 case FRMR + ABM: 210 hd_message (hdp, "FRMR received: link down"); 211 (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_xcp); 212 #ifdef HDLCDEBUG 213 hd_dumptrace (hdp); 214 #endif 215 hd_flush (hdp->hd_ifp); 216 hd_writeinternal (hdp, SABM, pf); 217 hdp->hd_state = WAIT_UA; 218 SET_TIMER (hdp); 219 break; 220 221 case RR + ABM: 222 case RNR + ABM: 223 case REJ + ABM: 224 process_sframe (hdp, (struct Hdlc_sframe *)frame, frametype); 225 break; 226 227 case IFRAME + ABM: 228 queued = process_iframe (hdp, fbuf, (struct Hdlc_iframe *)frame); 229 break; 230 231 case IFRAME + SABM_SENT: 232 case RR + SABM_SENT: 233 case RNR + SABM_SENT: 234 case REJ + SABM_SENT: 235 hd_writeinternal (hdp, DM, POLLON); 236 hdp->hd_state = DM_SENT; 237 SET_TIMER (hdp); 238 break; 239 240 case IFRAME + WAIT_SABM: 241 case RR + WAIT_SABM: 242 case RNR + WAIT_SABM: 243 case REJ + WAIT_SABM: 244 hd_writeinternal (hdp, FRMR, POLLOFF); 245 SET_TIMER (hdp); 246 break; 247 248 case ILLEGAL + SABM_SENT: 249 hdp->hd_unknown++; 250 hd_writeinternal (hdp, DM, POLLOFF); 251 hdp->hd_state = DM_SENT; 252 SET_TIMER (hdp); 253 break; 254 255 case ILLEGAL + ABM: 256 hd_message (hdp, "Unknown frame received: link down"); 257 (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_xcp); 258 case ILLEGAL + WAIT_SABM: 259 hdp->hd_unknown++; 260 #ifdef HDLCDEBUG 261 hd_dumptrace (hdp); 262 #endif 263 hd_writeinternal (hdp, FRMR, POLLOFF); 264 hdp->hd_state = WAIT_SABM; 265 SET_TIMER (hdp); 266 break; 267 } 268 269 return (queued); 270 } 271 272 process_iframe (hdp, fbuf, frame) 273 register struct hdcb *hdp; 274 struct mbuf *fbuf; 275 register struct Hdlc_iframe *frame; 276 { 277 register int nr = frame -> nr, 278 ns = frame -> ns, 279 pf = frame -> pf; 280 register int queued = FALSE; 281 282 /* 283 * Validate the iframe's N(R) value. It's N(R) value must be in 284 * sync with our V(S) value and our "last received nr". 285 */ 286 287 if (valid_nr (hdp, nr, FALSE) == FALSE) { 288 frame_reject (hdp, Z, frame); 289 return (queued); 290 } 291 292 293 /* 294 * This section tests the IFRAME for proper sequence. That is, it's 295 * sequence number N(S) MUST be equal to V(S). 296 */ 297 298 if (ns != hdp->hd_vr) { 299 hdp->hd_invalid_ns++; 300 if (pf || (hdp->hd_condition & REJ_CONDITION) == 0) { 301 hdp->hd_condition |= REJ_CONDITION; 302 /* 303 * Flush the transmit queue. This is ugly but we 304 * have no choice. A reject response must be 305 * immediately sent to the DCE. Failure to do so 306 * may result in another out of sequence iframe 307 * arriving (and thus sending another reject) 308 * before the first reject is transmitted. This 309 * will cause the DCE to receive two or more 310 * rejects back to back, which must never happen. 311 */ 312 hd_flush (hdp->hd_ifp); 313 hd_writeinternal (hdp, REJ, pf); 314 } 315 return (queued); 316 } 317 hdp->hd_condition &= ~REJ_CONDITION; 318 319 /* 320 * This section finally tests the IFRAME's sequence number against 321 * the window size (K) and the sequence number of the last frame 322 * we have acknowledged. If the IFRAME is completely correct then 323 * it is queued for the packet level. 324 */ 325 326 if (ns != (hdp->hd_lasttxnr + hdp->hd_xcp->xc_lwsize) % MODULUS) { 327 hdp->hd_vr = (hdp->hd_vr + 1) % MODULUS; 328 if (pf == 1) { 329 /* Must generate a RR or RNR with final bit on. */ 330 hd_writeinternal (hdp, RR, POLLON); 331 } else 332 /* 333 * Hopefully we can piggyback the RR, if not we will generate 334 * a RR when T3 timer expires. 335 */ 336 if (hdp -> hd_rrtimer == 0) 337 hdp->hd_rrtimer = hd_t3; 338 339 /* Forward iframe to packet level of X.25. */ 340 fbuf -> m_off += HDHEADERLN; 341 fbuf -> m_len -= HDHEADERLN; 342 #ifdef BSD4_3 343 fbuf->m_act = 0; /* probably not necessary */ 344 #else 345 { 346 register struct mbuf *m; 347 348 for (m = fbuf; m -> m_next; m = m -> m_next) 349 m -> m_act = (struct mbuf *) 0; 350 m -> m_act = (struct mbuf *) 1; 351 } 352 #endif 353 pk_input (fbuf, hdp->hd_xcp); 354 queued = TRUE; 355 hd_start (hdp); 356 } else { 357 /* 358 * Here if the remote station has transmitted more iframes then 359 * the number which have been acknowledged plus K. 360 */ 361 hdp->hd_invalid_ns++; 362 frame_reject (hdp, W, frame); 363 } 364 return (queued); 365 } 366 367 /* 368 * This routine is used to determine if a value (the middle parameter) 369 * is between two other values. The low value is the first parameter 370 * the high value is the last parameter. The routine checks the middle 371 * value to see if it is within the range of the first and last values. 372 * The reason we need this routine is the values are modulo some base 373 * hence a simple test for greater or less than is not sufficient. 374 */ 375 376 bool 377 range_check (rear, value, front) 378 int rear, 379 value, 380 front; 381 { 382 register bool result = FALSE; 383 384 if (front > rear) 385 result = (rear <= value) && (value <= front); 386 else 387 result = (rear <= value) || (value <= front); 388 389 return (result); 390 } 391 392 /* 393 * This routine handles all the frame reject conditions which can 394 * arise as a result of secondary processing. The frame reject 395 * condition Y (frame length error) are handled elsewhere. 396 */ 397 398 static 399 frame_reject (hdp, rejectcode, frame) 400 struct hdcb *hdp; 401 struct Hdlc_iframe *frame; 402 { 403 register struct Frmr_frame *frmr = &hd_frmr; 404 405 frmr -> frmr_control = ((struct Hdlc_frame *) frame) -> control; 406 407 frmr -> frmr_ns = frame -> ns; 408 frmr -> frmr_f1_0 = 0; 409 frmr -> frmr_nr = frame -> nr; 410 frmr -> frmr_f2_0 = 0; 411 412 frmr -> frmr_0000 = 0; 413 frmr -> frmr_w = frmr -> frmr_x = frmr -> frmr_y = 414 frmr -> frmr_z = 0; 415 switch (rejectcode) { 416 case Z: 417 frmr -> frmr_z = 1;/* invalid N(R). */ 418 break; 419 420 case Y: 421 frmr -> frmr_y = 1;/* iframe length error. */ 422 break; 423 424 case X: 425 frmr -> frmr_x = 1;/* invalid information field. */ 426 frmr -> frmr_w = 1; 427 break; 428 429 case W: 430 frmr -> frmr_w = 1;/* invalid N(S). */ 431 } 432 433 hd_writeinternal (hdp, FRMR, POLLOFF); 434 435 hdp->hd_state = WAIT_SABM; 436 SET_TIMER (hdp); 437 } 438 439 /* 440 * This procedure is invoked when ever we receive a supervisor 441 * frame such as RR, RNR and REJ. All processing for these 442 * frames is done here. 443 */ 444 445 process_sframe (hdp, frame, frametype) 446 register struct hdcb *hdp; 447 register struct Hdlc_sframe *frame; 448 int frametype; 449 { 450 register int nr = frame -> nr, pf = frame -> pf, pollbit = 0; 451 452 if (valid_nr (hdp, nr, pf) == TRUE) { 453 switch (frametype) { 454 case RR: 455 hdp->hd_condition &= ~REMOTE_RNR_CONDITION; 456 break; 457 458 case RNR: 459 hdp->hd_condition |= REMOTE_RNR_CONDITION; 460 hdp->hd_retxcnt = 0; 461 break; 462 463 case REJ: 464 hdp->hd_condition &= ~REMOTE_RNR_CONDITION; 465 rej_routine (hdp, nr); 466 } 467 468 if (pf == 1) { 469 hdp->hd_retxcnt = 0; 470 hdp->hd_condition &= ~TIMER_RECOVERY_CONDITION; 471 472 /* If any iframes have been queued because of the 473 timer condition, transmit then now. */ 474 if (hdp->hd_condition & REMOTE_RNR_CONDITION) { 475 /* Remote is busy or timer condition, so only 476 send one. */ 477 if (hdp->hd_vs != hdp->hd_retxqi) 478 hd_send_iframe (hdp, hdp->hd_retxq[hdp->hd_vs], pollbit); 479 } 480 else /* Flush the retransmit list first. */ 481 while (hdp->hd_vs != hdp->hd_retxqi) 482 hd_send_iframe (hdp, hdp->hd_retxq[hdp->hd_vs], POLLOFF); 483 } 484 485 hd_start (hdp); 486 } else 487 frame_reject (hdp, Z, (struct Hdlc_iframe *)frame); /* Invalid N(R). */ 488 } 489 490 /* 491 * This routine tests the validity of the N(R) which we have received. 492 * If it is ok, then all the iframes which it acknowledges (if any) 493 * will be freed. 494 */ 495 496 bool 497 valid_nr (hdp, nr, finalbit) 498 register struct hdcb *hdp; 499 register int finalbit; 500 { 501 /* Make sure it really does acknowledge something. */ 502 if (hdp->hd_lastrxnr == nr) 503 return (TRUE); 504 505 /* 506 * This section validates the frame's N(R) value. It's N(R) value 507 * must be in syncronization with our V(S) value and our "last 508 * received nr" variable. If it is correct then we are able to send 509 * more IFRAME's, else frame reject condition is entered. 510 */ 511 512 if (range_check (hdp->hd_lastrxnr, nr, hdp->hd_vs) == FALSE) { 513 if ((hdp->hd_condition & TIMER_RECOVERY_CONDITION) && 514 range_check (hdp->hd_vs, nr, hdp->hd_xx) == TRUE) 515 hdp->hd_vs = nr; 516 517 else { 518 hdp->hd_invalid_nr++; 519 return (FALSE); 520 } 521 } 522 523 /* 524 * If we get to here, we do have a valid frame but it might be out 525 * of sequence. However, we should still accept the receive state 526 * number N(R) since it has already passed our previous test and it 527 * does acknowledge frames which we are sending. 528 */ 529 530 KILL_TIMER (hdp); 531 free_iframes (hdp, &nr, finalbit);/* Free all acknowledged iframes */ 532 if (nr != hdp->hd_vs) 533 SET_TIMER (hdp); 534 535 return (TRUE); 536 } 537 538 /* 539 * This routine determines how many iframes need to be retransmitted. 540 * It then resets the Send State Variable V(S) to accomplish this. 541 */ 542 543 static 544 rej_routine (hdp, rejnr) 545 register struct hdcb *hdp; 546 register int rejnr; 547 { 548 register int anchor; 549 550 /* 551 * Flush the output queue. Any iframes queued for 552 * transmission will be out of sequence. 553 */ 554 555 hd_flush (hdp->hd_ifp); 556 557 /* 558 * Determine how many frames should be re-transmitted. In the case 559 * of a normal REJ this should be 1 to K. In the case of a timer 560 * recovery REJ (ie. a REJ with the Final Bit on) this could be 0. 561 */ 562 563 anchor = hdp->hd_vs; 564 if (hdp->hd_condition & TIMER_RECOVERY_CONDITION) 565 anchor = hdp->hd_xx; 566 567 anchor = (anchor - rejnr + 8) % MODULUS; 568 569 if (anchor > 0) { 570 571 /* There is at least one iframe to retransmit. */ 572 KILL_TIMER (hdp); 573 hdp->hd_vs = rejnr; 574 575 while (hdp->hd_vs != hdp->hd_retxqi) 576 hd_send_iframe (hdp, hdp->hd_retxq[hdp->hd_vs], POLLOFF); 577 578 } 579 hd_start (hdp); 580 } 581 582 /* 583 * This routine frees iframes from the retransmit queue. It is called 584 * when a previously written iframe is acknowledged. 585 */ 586 587 static 588 free_iframes (hdp, nr, finalbit) 589 register struct hdcb *hdp; 590 int *nr; 591 register int finalbit; 592 593 { 594 register int i, k; 595 596 /* 597 * We need to do the following because of a funny quirk in the 598 * protocol. This case occures when in Timer recovery condition 599 * we get a N(R) which acknowledges all the outstanding iframes 600 * but with the Final Bit off. In this case we need to save the last 601 * iframe for possible retransmission even though it has already been 602 * acknowledged! 603 */ 604 605 if ((hdp->hd_condition & TIMER_RECOVERY_CONDITION) && *nr == hdp->hd_xx && finalbit == 0) { 606 *nr = (*nr - 1 + 8) % MODULUS; 607 /* printf ("QUIRK\n"); */ 608 } 609 610 k = (*nr - hdp->hd_lastrxnr + 8) % MODULUS; 611 612 /* Loop here freeing all acknowledged iframes. */ 613 for (i = 0; i < k; ++i) { 614 m_freem (hdp->hd_retxq[hdp->hd_lastrxnr]); 615 hdp->hd_retxq[hdp->hd_lastrxnr] = 0; 616 hdp->hd_lastrxnr = (hdp->hd_lastrxnr + 1) % MODULUS; 617 } 618 619 } 620