1 /* 2 * Copyright (c) University of British Columbia, 1984 3 * Copyright (C) Computer Science Department IV, 4 * University of Erlangen-Nuremberg, Germany, 1992 5 * Copyright (c) 1991, 1992 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by the 9 * Laboratory for Computation Vision and the Computer Science Department 10 * of the the University of British Columbia and the Computer Science 11 * Department (IV) of the University of Erlangen-Nuremberg, Germany. 12 * 13 * %sccs.include.redist.c% 14 * 15 * @(#)pk_subr.c 7.23 (Berkeley) 12/08/92 16 */ 17 18 #include <sys/param.h> 19 #include <sys/systm.h> 20 #include <sys/mbuf.h> 21 #include <sys/socket.h> 22 #include <sys/protosw.h> 23 #include <sys/socketvar.h> 24 #include <sys/errno.h> 25 #include <sys/time.h> 26 #include <sys/kernel.h> 27 28 #include <net/if.h> 29 30 #include <netccitt/dll.h> 31 #include <netccitt/x25.h> 32 #include <netccitt/x25err.h> 33 #include <netccitt/pk.h> 34 #include <netccitt/pk_var.h> 35 36 int pk_sendspace = 1024 * 2 + 8; 37 int pk_recvspace = 1024 * 2 + 8; 38 39 struct pklcd_q pklcd_q = {&pklcd_q, &pklcd_q}; 40 41 struct x25bitslice x25_bitslice[] = { 42 /* mask, shift value */ 43 { 0xf0, 0x4 }, 44 { 0xf, 0x0 }, 45 { 0x80, 0x7 }, 46 { 0x40, 0x6 }, 47 { 0x30, 0x4 }, 48 { 0xe0, 0x5 }, 49 { 0x10, 0x4 }, 50 { 0xe, 0x1 }, 51 { 0x1, 0x0 } 52 }; 53 54 55 /* 56 * Attach X.25 protocol to socket, allocate logical channel descripter 57 * and buffer space, and enter LISTEN state if we are to accept 58 * IN-COMMING CALL packets. 59 * 60 */ 61 62 struct pklcd * 63 pk_attach (so) 64 struct socket *so; 65 { 66 register struct pklcd *lcp; 67 register int error = ENOBUFS; 68 int pk_output(); 69 70 MALLOC(lcp, struct pklcd *, sizeof (*lcp), M_PCB, M_NOWAIT); 71 if (lcp) { 72 bzero ((caddr_t)lcp, sizeof (*lcp)); 73 insque (&lcp -> lcd_q, &pklcd_q); 74 lcp -> lcd_state = READY; 75 lcp -> lcd_send = pk_output; 76 if (so) { 77 error = soreserve (so, pk_sendspace, pk_recvspace); 78 lcp -> lcd_so = so; 79 if (so -> so_options & SO_ACCEPTCONN) 80 lcp -> lcd_state = LISTEN; 81 } else 82 sbreserve (&lcp -> lcd_sb, pk_sendspace); 83 } 84 if (so) { 85 so -> so_pcb = (caddr_t) lcp; 86 so -> so_error = error; 87 } 88 return (lcp); 89 } 90 91 /* 92 * Disconnect X.25 protocol from socket. 93 */ 94 95 pk_disconnect (lcp) 96 register struct pklcd *lcp; 97 { 98 register struct socket *so = lcp -> lcd_so; 99 register struct pklcd *l, *p; 100 101 switch (lcp -> lcd_state) { 102 case LISTEN: 103 for (p = 0, l = pk_listenhead; l && l != lcp; p = l, l = l -> lcd_listen); 104 if (p == 0) { 105 if (l != 0) 106 pk_listenhead = l -> lcd_listen; 107 } 108 else 109 if (l != 0) 110 p -> lcd_listen = l -> lcd_listen; 111 pk_close (lcp); 112 break; 113 114 case READY: 115 pk_acct (lcp); 116 pk_close (lcp); 117 break; 118 119 case SENT_CLEAR: 120 case RECEIVED_CLEAR: 121 break; 122 123 default: 124 pk_acct (lcp); 125 if (so) { 126 soisdisconnecting (so); 127 sbflush (&so -> so_rcv); 128 } 129 pk_clear (lcp, 241, 0); /* Normal Disconnect */ 130 131 } 132 } 133 134 /* 135 * Close an X.25 Logical Channel. Discard all space held by the 136 * connection and internal descriptors. Wake up any sleepers. 137 */ 138 139 pk_close (lcp) 140 struct pklcd *lcp; 141 { 142 register struct socket *so = lcp -> lcd_so; 143 144 /* 145 * If the X.25 connection is torn down due to link 146 * level failure (e.g. LLC2 FRMR) and at the same the user 147 * level is still filling up the socket send buffer that 148 * send buffer is locked. An attempt to sbflush() that send 149 * buffer will lead us into - no, not temptation but - panic! 150 * So - we'll just check wether the send buffer is locked 151 * and if that's the case we'll mark the lcp as zombie and 152 * have the pk_timer() do the cleaning ... 153 */ 154 155 if (so && so -> so_snd.sb_flags & SB_LOCK) 156 lcp -> lcd_state = LCN_ZOMBIE; 157 else 158 pk_freelcd (lcp); 159 160 if (so == NULL) 161 return; 162 163 so -> so_pcb = 0; 164 soisdisconnected (so); 165 /* sofree (so); /* gak!!! you can't do that here */ 166 } 167 168 /* 169 * Create a template to be used to send X.25 packets on a logical 170 * channel. It allocates an mbuf and fills in a skeletal packet 171 * depending on its type. This packet is passed to pk_output where 172 * the remainer of the packet is filled in. 173 */ 174 175 struct mbuf * 176 pk_template (lcn, type) 177 int lcn, type; 178 { 179 register struct mbuf *m; 180 register struct x25_packet *xp; 181 182 MGETHDR (m, M_DONTWAIT, MT_HEADER); 183 if (m == 0) 184 panic ("pk_template"); 185 m -> m_act = 0; 186 187 /* 188 * Efficiency hack: leave a four byte gap at the beginning 189 * of the packet level header with the hope that this will 190 * be enough room for the link level to insert its header. 191 */ 192 m -> m_data += max_linkhdr; 193 m -> m_pkthdr.len = m -> m_len = PKHEADERLN; 194 195 xp = mtod (m, struct x25_packet *); 196 *(long *)xp = 0; /* ugly, but fast */ 197 /* xp -> q_bit = 0;*/ 198 X25SBITS(xp -> bits, fmt_identifier, 1); 199 /* xp -> lc_group_number = 0;*/ 200 201 SET_LCN(xp, lcn); 202 xp -> packet_type = type; 203 204 return (m); 205 } 206 207 /* 208 * This routine restarts all the virtual circuits. Actually, 209 * the virtual circuits are not "restarted" as such. Instead, 210 * any active switched circuit is simply returned to READY 211 * state. 212 */ 213 214 pk_restart (pkp, restart_cause) 215 register struct pkcb *pkp; 216 int restart_cause; 217 { 218 register struct mbuf *m; 219 register struct pklcd *lcp; 220 register int i; 221 222 /* Restart all logical channels. */ 223 if (pkp -> pk_chan == 0) 224 return; 225 226 /* 227 * Don't do this if we're doing a restart issued from 228 * inside pk_connect() --- which is only done if and 229 * only if the X.25 link is down, i.e. a RESTART needs 230 * to be done to get it up. 231 */ 232 if (!(pkp -> pk_dxerole & DTE_CONNECTPENDING)) { 233 for (i = 1; i <= pkp -> pk_maxlcn; ++i) 234 if ((lcp = pkp -> pk_chan[i]) != NULL) { 235 if (lcp -> lcd_so) { 236 lcp -> lcd_so -> so_error = ENETRESET; 237 pk_close (lcp); 238 } else { 239 pk_flush (lcp); 240 lcp -> lcd_state = READY; 241 if (lcp -> lcd_upper) 242 lcp -> lcd_upper (lcp, 0); 243 } 244 } 245 } 246 247 if (restart_cause < 0) 248 return; 249 250 pkp -> pk_state = DTE_SENT_RESTART; 251 pkp -> pk_dxerole &= ~(DTE_PLAYDCE | DTE_PLAYDTE); 252 lcp = pkp -> pk_chan[0]; 253 m = lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESTART); 254 m -> m_pkthdr.len = m -> m_len += 2; 255 mtod (m, struct x25_packet *) -> packet_data = 0; /* DTE only */ 256 mtod (m, octet *)[4] = restart_cause; 257 pk_output (lcp); 258 } 259 260 261 /* 262 * This procedure frees up the Logical Channel Descripter. 263 */ 264 265 pk_freelcd (lcp) 266 register struct pklcd *lcp; 267 { 268 if (lcp == NULL) 269 return; 270 271 if (lcp -> lcd_lcn > 0) 272 lcp -> lcd_pkp -> pk_chan[lcp -> lcd_lcn] = NULL; 273 274 pk_flush (lcp); 275 remque (&lcp -> lcd_q); 276 free ((caddr_t)lcp, M_PCB); 277 } 278 279 280 /* 281 * Bind a address and protocol value to a socket. The important 282 * part is the protocol value - the first four characters of the 283 * Call User Data field. 284 */ 285 286 #define XTRACTPKP(rt) ((rt)->rt_flags & RTF_GATEWAY ? \ 287 ((rt)->rt_llinfo ? \ 288 (struct pkcb *) ((struct rtentry *)((rt)->rt_llinfo))->rt_llinfo : \ 289 (struct pkcb *) NULL) : \ 290 (struct pkcb *)((rt)->rt_llinfo)) 291 292 pk_bind (lcp, nam) 293 struct pklcd *lcp; 294 struct mbuf *nam; 295 { 296 register struct pkcb *pkp; 297 register struct pklcd *pp; 298 register struct sockaddr_x25 *sa; 299 register struct rtentry *rt; 300 301 if (nam == NULL) 302 return (EADDRNOTAVAIL); 303 if (lcp -> lcd_ceaddr) /* XXX */ 304 return (EADDRINUSE); 305 if (pk_checksockaddr (nam)) 306 return (EINVAL); 307 sa = mtod (nam, struct sockaddr_x25 *); 308 309 /* 310 * If the user wishes to accept calls only from a particular 311 * net (net != 0), make sure the net is known 312 */ 313 314 if ( !(rt = rtalloc1(sa, 1))) 315 return (ENETUNREACH); 316 pkp = XTRACTPKP(rt); 317 318 /* 319 * For ISO's sake permit default listeners, but only one such . . . 320 */ 321 for (pp = pk_listenhead; pp; pp = pp -> lcd_listen) { 322 register struct sockaddr_x25 *sa2 = pp -> lcd_ceaddr; 323 if ((sa2 -> x25_udlen == sa -> x25_udlen) && 324 (sa2 -> x25_udlen == 0 || 325 (bcmp (sa2 -> x25_udata, sa -> x25_udata, 326 min (sa2 -> x25_udlen, sa -> x25_udlen)) == 0))) 327 return (EADDRINUSE); 328 } 329 lcp -> lcd_laddr = *sa; 330 lcp -> lcd_ceaddr = &lcp -> lcd_laddr; 331 return (0); 332 } 333 334 /* 335 * Include a bound control block in the list of listeners. 336 */ 337 pk_listen (lcp) 338 register struct pklcd *lcp; 339 { 340 register struct pklcd **pp; 341 342 if (lcp -> lcd_ceaddr == 0) 343 return (EDESTADDRREQ); 344 345 lcp -> lcd_state = LISTEN; 346 /* 347 * Add default listener at end, any others at start. 348 */ 349 if (lcp -> lcd_ceaddr -> x25_udlen == 0) { 350 for (pp = &pk_listenhead; *pp; ) 351 pp = &((*pp) -> lcd_listen); 352 *pp = lcp; 353 } else { 354 lcp -> lcd_listen = pk_listenhead; 355 pk_listenhead = lcp; 356 } 357 return (0); 358 } 359 /* 360 * Include a listening control block for the benefit of other protocols. 361 */ 362 pk_protolisten (spi, spilen, callee) 363 int (*callee) (); 364 { 365 register struct pklcd *lcp = pk_attach ((struct socket *)0); 366 register struct mbuf *nam; 367 register struct sockaddr_x25 *sa; 368 int error = ENOBUFS; 369 370 if (lcp) { 371 if (nam = m_getclr (MT_SONAME, M_DONTWAIT)) { 372 sa = mtod (nam, struct sockaddr_x25 *); 373 sa -> x25_family = AF_CCITT; 374 sa -> x25_len = nam -> m_len = sizeof (*sa); 375 sa -> x25_udlen = spilen; 376 sa -> x25_udata[0] = spi; 377 lcp -> lcd_upper = callee; 378 lcp -> lcd_flags = X25_MBS_HOLD; 379 if ((error = pk_bind (lcp, nam)) == 0) 380 error = pk_listen (lcp); 381 (void) m_free (nam); 382 } 383 if (error) 384 pk_freelcd (lcp); 385 } 386 return error; /* Hopefully Zero !*/ 387 } 388 389 /* 390 * Associate a logical channel descriptor with a network. 391 * Fill in the default network specific parameters and then 392 * set any parameters explicitly specified by the user or 393 * by the remote DTE. 394 */ 395 396 pk_assoc (pkp, lcp, sa) 397 register struct pkcb *pkp; 398 register struct pklcd *lcp; 399 register struct sockaddr_x25 *sa; 400 { 401 402 lcp -> lcd_pkp = pkp; 403 lcp -> lcd_packetsize = pkp -> pk_xcp -> xc_psize; 404 lcp -> lcd_windowsize = pkp -> pk_xcp -> xc_pwsize; 405 lcp -> lcd_rsn = MODULUS - 1; 406 pkp -> pk_chan[lcp -> lcd_lcn] = lcp; 407 408 if (sa -> x25_opts.op_psize) 409 lcp -> lcd_packetsize = sa -> x25_opts.op_psize; 410 else 411 sa -> x25_opts.op_psize = lcp -> lcd_packetsize; 412 if (sa -> x25_opts.op_wsize) 413 lcp -> lcd_windowsize = sa -> x25_opts.op_wsize; 414 else 415 sa -> x25_opts.op_wsize = lcp -> lcd_windowsize; 416 sa -> x25_net = pkp -> pk_xcp -> xc_addr.x25_net; 417 lcp -> lcd_flags |= sa -> x25_opts.op_flags; 418 lcp -> lcd_stime = time.tv_sec; 419 } 420 421 pk_connect (lcp, sa) 422 register struct pklcd *lcp; 423 register struct sockaddr_x25 *sa; 424 { 425 register struct pkcb *pkp; 426 register struct rtentry *rt; 427 register struct rtentry *nrt; 428 429 struct rtentry *npaidb_enter(); 430 struct pkcb *pk_newlink(); 431 432 if (sa -> x25_addr[0] == '\0') 433 return (EDESTADDRREQ); 434 435 /* 436 * Is the destination address known? 437 */ 438 if (!(rt = rtalloc1 (sa, 1))) 439 return (ENETUNREACH); 440 441 if (!(pkp = XTRACTPKP(rt))) 442 pkp = pk_newlink((struct x25_ifaddr *) (rt -> rt_ifa), 443 (caddr_t) 0); 444 445 /* 446 * Have we entered the LLC address? 447 */ 448 if (nrt = npaidb_enter(rt -> rt_gateway, rt_key(rt), rt, 0)) 449 pkp -> pk_llrt = nrt; 450 451 /* 452 * Have we allocated an LLC2 link yet? 453 */ 454 if (pkp->pk_llnext == (caddr_t)0 && pkp->pk_llctlinput) { 455 struct dll_ctlinfo ctlinfo; 456 457 ctlinfo.dlcti_rt = rt; 458 ctlinfo.dlcti_pcb = (caddr_t) pkp; 459 ctlinfo.dlcti_conf = 460 (struct dllconfig *) (&((struct x25_ifaddr *)(rt->rt_ifa))->ia_xc); 461 pkp->pk_llnext = 462 (pkp->pk_llctlinput)(PRC_CONNECT_REQUEST, 0, &ctlinfo); 463 } 464 465 if (pkp -> pk_state != DTE_READY && pkp -> pk_state != DTE_WAITING) 466 return (ENETDOWN); 467 if ((lcp -> lcd_lcn = pk_getlcn (pkp)) == 0) 468 return (EMFILE); 469 470 lcp -> lcd_faddr = *sa; 471 lcp -> lcd_ceaddr = & lcp -> lcd_faddr; 472 pk_assoc (pkp, lcp, lcp -> lcd_ceaddr); 473 474 /* 475 * If the link is not up yet, initiate an X.25 RESTART 476 */ 477 if (pkp -> pk_state == DTE_WAITING) { 478 pkp -> pk_dxerole |= DTE_CONNECTPENDING; 479 pk_ctlinput(PRC_LINKUP, (struct sockaddr *)0, pkp); 480 if (lcp -> lcd_so) 481 soisconnecting (lcp -> lcd_so); 482 return 0; 483 } 484 485 if (lcp -> lcd_so) 486 soisconnecting (lcp -> lcd_so); 487 lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL); 488 pk_callrequest (lcp, lcp -> lcd_ceaddr, pkp -> pk_xcp); 489 return (*pkp -> pk_ia -> ia_start) (lcp); 490 } 491 492 /* 493 * Complete all pending X.25 call requests --- this gets called after 494 * the X.25 link has been restarted. 495 */ 496 #define RESHUFFLELCN(maxlcn, lcn) ((maxlcn) - (lcn) + 1) 497 498 pk_callcomplete(pkp) 499 register struct pkcb *pkp; 500 { 501 register struct pklcd *lcp; 502 register int i; 503 register int ni; 504 505 506 if (pkp -> pk_dxerole & DTE_CONNECTPENDING) 507 pkp -> pk_dxerole &= ~DTE_CONNECTPENDING; 508 else return; 509 510 if (pkp -> pk_chan == 0) 511 return; 512 513 /* 514 * We pretended to be a DTE for allocating lcns, if 515 * it turns out that we are in reality performing as a 516 * DCE we need to reshuffle the lcps. 517 * 518 * /+---------------+-------- - 519 * / | a (maxlcn-1) | \ 520 * / +---------------+ \ 521 * +--- * | b (maxlcn-2) | \ 522 * | \ +---------------+ \ 523 * r | \ | c (maxlcn-3) | \ 524 * e | \+---------------+ | 525 * s | | . | 526 * h | | . | m 527 * u | | . | a 528 * f | | . | x 529 * f | | . | l 530 * l | /+---------------+ | c 531 * e | / | c' ( 3 ) | | n 532 * | / +---------------+ | 533 * +--> * | b' ( 2 ) | / 534 * \ +---------------+ / 535 * \ | a' ( 1 ) | / 536 * \+---------------+ / 537 * | 0 | / 538 * +---------------+-------- - 539 * 540 */ 541 if (pkp -> pk_dxerole & DTE_PLAYDCE) { 542 /* Sigh, reshuffle it */ 543 for (i = pkp -> pk_maxlcn; i > 0; --i) 544 if (pkp -> pk_chan[i]) { 545 ni = RESHUFFLELCN(pkp -> pk_maxlcn, i); 546 pkp -> pk_chan[ni] = pkp -> pk_chan[i]; 547 pkp -> pk_chan[i] = NULL; 548 pkp -> pk_chan[ni] -> lcd_lcn = ni; 549 } 550 } 551 552 for (i = 1; i <= pkp -> pk_maxlcn; ++i) 553 if ((lcp = pkp -> pk_chan[i]) != NULL) { 554 /* if (lcp -> lcd_so) 555 soisconnecting (lcp -> lcd_so); */ 556 lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL); 557 pk_callrequest (lcp, lcp -> lcd_ceaddr, pkp -> pk_xcp); 558 (*pkp -> pk_ia -> ia_start)(lcp); 559 } 560 } 561 562 struct bcdinfo { 563 octet *cp; 564 unsigned posn; 565 }; 566 /* 567 * Build the rest of the CALL REQUEST packet. Fill in calling 568 * address, facilities fields and the user data field. 569 */ 570 571 pk_callrequest (lcp, sa, xcp) 572 struct pklcd *lcp; 573 register struct sockaddr_x25 *sa; 574 register struct x25config *xcp; 575 { 576 register struct x25_calladdr *a; 577 register struct mbuf *m = lcp -> lcd_template; 578 register struct x25_packet *xp = mtod (m, struct x25_packet *); 579 struct bcdinfo b; 580 581 if (lcp -> lcd_flags & X25_DBIT) 582 X25SBITS(xp -> bits, d_bit, 1); 583 a = (struct x25_calladdr *) &xp -> packet_data; 584 b.cp = (octet *) a -> address_field; 585 b.posn = 0; 586 X25SBITS(a -> addrlens, called_addrlen, to_bcd (&b, sa, xcp)); 587 X25SBITS(a -> addrlens, calling_addrlen, to_bcd (&b, &xcp -> xc_addr, xcp)); 588 if (b.posn & 0x01) 589 *b.cp++ &= 0xf0; 590 m -> m_pkthdr.len = m -> m_len += b.cp - (octet *) a; 591 592 if (lcp -> lcd_facilities) { 593 m -> m_pkthdr.len += 594 (m -> m_next = lcp -> lcd_facilities) -> m_pkthdr.len; 595 lcp -> lcd_facilities = 0; 596 } else 597 pk_build_facilities (m, sa, (int)xcp -> xc_type); 598 599 m_copyback (m, m -> m_pkthdr.len, sa -> x25_udlen, sa -> x25_udata); 600 } 601 602 pk_build_facilities (m, sa, type) 603 register struct mbuf *m; 604 struct sockaddr_x25 *sa; 605 { 606 register octet *cp; 607 register octet *fcp; 608 register int revcharge; 609 610 cp = mtod (m, octet *) + m -> m_len; 611 fcp = cp + 1; 612 revcharge = sa -> x25_opts.op_flags & X25_REVERSE_CHARGE ? 1 : 0; 613 /* 614 * This is specific to Datapac X.25(1976) DTEs. International 615 * calls must have the "hi priority" bit on. 616 */ 617 if (type == X25_1976 && sa -> x25_opts.op_psize == X25_PS128) 618 revcharge |= 02; 619 if (revcharge) { 620 *fcp++ = FACILITIES_REVERSE_CHARGE; 621 *fcp++ = revcharge; 622 } 623 switch (type) { 624 case X25_1980: 625 case X25_1984: 626 *fcp++ = FACILITIES_PACKETSIZE; 627 *fcp++ = sa -> x25_opts.op_psize; 628 *fcp++ = sa -> x25_opts.op_psize; 629 630 *fcp++ = FACILITIES_WINDOWSIZE; 631 *fcp++ = sa -> x25_opts.op_wsize; 632 *fcp++ = sa -> x25_opts.op_wsize; 633 } 634 *cp = fcp - cp - 1; 635 m -> m_pkthdr.len = (m -> m_len += *cp + 1); 636 } 637 638 to_bcd (b, sa, xcp) 639 register struct bcdinfo *b; 640 struct sockaddr_x25 *sa; 641 register struct x25config *xcp; 642 { 643 register char *x = sa -> x25_addr; 644 unsigned start = b -> posn; 645 /* 646 * The nodnic and prepnd0 stuff looks tedious, 647 * but it does allow full X.121 addresses to be used, 648 * which is handy for routing info (& OSI type 37 addresses). 649 */ 650 if (xcp -> xc_addr.x25_net && (xcp -> xc_nodnic || xcp -> xc_prepnd0)) { 651 char dnicname[sizeof(long) * NBBY/3 + 2]; 652 register char *p = dnicname; 653 654 sprintf (p, "%d", xcp -> xc_addr.x25_net & 0x7fff); 655 for (; *p; p++) /* *p == 0 means dnic matched */ 656 if ((*p ^ *x++) & 0x0f) 657 break; 658 if (*p || xcp -> xc_nodnic == 0) 659 x = sa -> x25_addr; 660 if (*p && xcp -> xc_prepnd0) { 661 if ((b -> posn)++ & 0x01) 662 *(b -> cp)++; 663 else 664 *(b -> cp) = 0; 665 } 666 } 667 while (*x) 668 if ((b -> posn)++ & 0x01) 669 *(b -> cp)++ |= *x++ & 0x0F; 670 else 671 *(b -> cp) = *x++ << 4; 672 return ((b -> posn) - start); 673 } 674 675 /* 676 * This routine gets the first available logical channel number. The 677 * search is 678 * - from the highest number to lowest number if playing DTE, and 679 * - from lowest to highest number if playing DCE. 680 */ 681 682 pk_getlcn (pkp) 683 register struct pkcb *pkp; 684 { 685 register int i; 686 687 if (pkp -> pk_chan == 0) 688 return (0); 689 if ( pkp -> pk_dxerole & DTE_PLAYDCE ) { 690 for (i = 1; i <= pkp -> pk_maxlcn; ++i) 691 if (pkp -> pk_chan[i] == NULL) 692 break; 693 } else { 694 for (i = pkp -> pk_maxlcn; i > 0; --i) 695 if (pkp -> pk_chan[i] == NULL) 696 break; 697 } 698 i = ( i > pkp -> pk_maxlcn ? 0 : i ); 699 return (i); 700 } 701 702 /* 703 * This procedure sends a CLEAR request packet. The lc state is 704 * set to "SENT_CLEAR". 705 */ 706 707 pk_clear (lcp, diagnostic, abortive) 708 register struct pklcd *lcp; 709 { 710 register struct mbuf *m = pk_template (lcp -> lcd_lcn, X25_CLEAR); 711 712 m -> m_len += 2; 713 m -> m_pkthdr.len += 2; 714 mtod (m, struct x25_packet *) -> packet_data = 0; 715 mtod (m, octet *)[4] = diagnostic; 716 if (lcp -> lcd_facilities) { 717 m -> m_next = lcp -> lcd_facilities; 718 m -> m_pkthdr.len += m -> m_next -> m_len; 719 lcp -> lcd_facilities = 0; 720 } 721 if (abortive) 722 lcp -> lcd_template = m; 723 else { 724 struct socket *so = lcp -> lcd_so; 725 struct sockbuf *sb = so ? & so -> so_snd : & lcp -> lcd_sb; 726 sbappendrecord (sb, m); 727 } 728 pk_output (lcp); 729 730 } 731 732 /* 733 * This procedure generates RNR's or RR's to inhibit or enable 734 * inward data flow, if the current state changes (blocked ==> open or 735 * vice versa), or if forced to generate one. One forces RNR's to ack data. 736 */ 737 pk_flowcontrol (lcp, inhibit, forced) 738 register struct pklcd *lcp; 739 { 740 inhibit = (inhibit != 0); 741 if (lcp == 0 || lcp -> lcd_state != DATA_TRANSFER || 742 (forced == 0 && lcp -> lcd_rxrnr_condition == inhibit)) 743 return; 744 lcp -> lcd_rxrnr_condition = inhibit; 745 lcp -> lcd_template = 746 pk_template (lcp -> lcd_lcn, inhibit ? X25_RNR : X25_RR); 747 pk_output (lcp); 748 } 749 750 /* 751 * This procedure sends a RESET request packet. It re-intializes 752 * virtual circuit. 753 */ 754 755 static 756 pk_reset (lcp, diagnostic) 757 register struct pklcd *lcp; 758 { 759 register struct mbuf *m; 760 register struct socket *so = lcp -> lcd_so; 761 762 if (lcp -> lcd_state != DATA_TRANSFER) 763 return; 764 765 if (so) 766 so -> so_error = ECONNRESET; 767 lcp -> lcd_reset_condition = TRUE; 768 769 /* Reset all the control variables for the channel. */ 770 pk_flush (lcp); 771 lcp -> lcd_window_condition = lcp -> lcd_rnr_condition = 772 lcp -> lcd_intrconf_pending = FALSE; 773 lcp -> lcd_rsn = MODULUS - 1; 774 lcp -> lcd_ssn = 0; 775 lcp -> lcd_output_window = lcp -> lcd_input_window = 776 lcp -> lcd_last_transmitted_pr = 0; 777 m = lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET); 778 m -> m_pkthdr.len = m -> m_len += 2; 779 mtod (m, struct x25_packet *) -> packet_data = 0; 780 mtod (m, octet *)[4] = diagnostic; 781 pk_output (lcp); 782 783 } 784 785 /* 786 * This procedure frees all data queued for output or delivery on a 787 * virtual circuit. 788 */ 789 790 pk_flush (lcp) 791 register struct pklcd *lcp; 792 { 793 register struct socket *so; 794 795 if (lcp -> lcd_template) 796 m_freem (lcp -> lcd_template); 797 798 if (lcp -> lcd_cps) { 799 m_freem (lcp -> lcd_cps); 800 lcp -> lcd_cps = 0; 801 } 802 if (lcp -> lcd_facilities) { 803 m_freem (lcp -> lcd_facilities); 804 lcp -> lcd_facilities = 0; 805 } 806 if (so = lcp -> lcd_so) 807 sbflush (&so -> so_snd); 808 else 809 sbflush (&lcp -> lcd_sb); 810 } 811 812 /* 813 * This procedure handles all local protocol procedure errors. 814 */ 815 816 pk_procerror (error, lcp, errstr, diagnostic) 817 register struct pklcd *lcp; 818 char *errstr; 819 { 820 821 pk_message (lcp -> lcd_lcn, lcp -> lcd_pkp -> pk_xcp, errstr); 822 823 switch (error) { 824 case CLEAR: 825 if (lcp -> lcd_so) { 826 lcp -> lcd_so -> so_error = ECONNABORTED; 827 soisdisconnecting (lcp -> lcd_so); 828 } 829 pk_clear (lcp, diagnostic, 1); 830 break; 831 832 case RESET: 833 pk_reset (lcp, diagnostic); 834 } 835 } 836 837 /* 838 * This procedure is called during the DATA TRANSFER state to check 839 * and process the P(R) values received in the DATA, RR OR RNR 840 * packets. 841 */ 842 843 pk_ack (lcp, pr) 844 struct pklcd *lcp; 845 unsigned pr; 846 { 847 register struct socket *so = lcp -> lcd_so; 848 849 if (lcp -> lcd_output_window == pr) 850 return (PACKET_OK); 851 if (lcp -> lcd_output_window < lcp -> lcd_ssn) { 852 if (pr < lcp -> lcd_output_window || pr > lcp -> lcd_ssn) { 853 pk_procerror (RESET, lcp, 854 "p(r) flow control error", 2); 855 return (ERROR_PACKET); 856 } 857 } 858 else { 859 if (pr < lcp -> lcd_output_window && pr > lcp -> lcd_ssn) { 860 pk_procerror (RESET, lcp, 861 "p(r) flow control error #2", 2); 862 return (ERROR_PACKET); 863 } 864 } 865 866 lcp -> lcd_output_window = pr; /* Rotate window. */ 867 if (lcp -> lcd_window_condition == TRUE) 868 lcp -> lcd_window_condition = FALSE; 869 870 if (so && ((so -> so_snd.sb_flags & SB_WAIT) || 871 (so -> so_snd.sb_flags & SB_NOTIFY))) 872 sowwakeup (so); 873 874 return (PACKET_OK); 875 } 876 877 /* 878 * This procedure decodes the X.25 level 3 packet returning a 879 * code to be used in switchs or arrays. 880 */ 881 882 pk_decode (xp) 883 register struct x25_packet *xp; 884 { 885 register int type; 886 887 if (X25GBITS(xp -> bits, fmt_identifier) != 1) 888 return (INVALID_PACKET); 889 #ifdef ancient_history 890 /* 891 * Make sure that the logical channel group number is 0. 892 * This restriction may be removed at some later date. 893 */ 894 if (xp -> lc_group_number != 0) 895 return (INVALID_PACKET); 896 #endif 897 /* 898 * Test for data packet first. 899 */ 900 if (!(xp -> packet_type & DATA_PACKET_DESIGNATOR)) 901 return (DATA); 902 903 /* 904 * Test if flow control packet (RR or RNR). 905 */ 906 if (!(xp -> packet_type & RR_OR_RNR_PACKET_DESIGNATOR)) 907 switch (xp -> packet_type & 0x1f) { 908 case X25_RR: 909 return (RR); 910 case X25_RNR: 911 return (RNR); 912 case X25_REJECT: 913 return (REJECT); 914 } 915 916 /* 917 * Determine the rest of the packet types. 918 */ 919 switch (xp -> packet_type) { 920 case X25_CALL: 921 type = CALL; 922 break; 923 924 case X25_CALL_ACCEPTED: 925 type = CALL_ACCEPTED; 926 break; 927 928 case X25_CLEAR: 929 type = CLEAR; 930 break; 931 932 case X25_CLEAR_CONFIRM: 933 type = CLEAR_CONF; 934 break; 935 936 case X25_INTERRUPT: 937 type = INTERRUPT; 938 break; 939 940 case X25_INTERRUPT_CONFIRM: 941 type = INTERRUPT_CONF; 942 break; 943 944 case X25_RESET: 945 type = RESET; 946 break; 947 948 case X25_RESET_CONFIRM: 949 type = RESET_CONF; 950 break; 951 952 case X25_RESTART: 953 type = RESTART; 954 break; 955 956 case X25_RESTART_CONFIRM: 957 type = RESTART_CONF; 958 break; 959 960 case X25_DIAGNOSTIC: 961 type = DIAG_TYPE; 962 break; 963 964 default: 965 type = INVALID_PACKET; 966 } 967 return (type); 968 } 969 970 /* 971 * A restart packet has been received. Print out the reason 972 * for the restart. 973 */ 974 975 pk_restartcause (pkp, xp) 976 struct pkcb *pkp; 977 register struct x25_packet *xp; 978 { 979 register struct x25config *xcp = pkp -> pk_xcp; 980 register int lcn = LCN(xp); 981 982 switch (xp -> packet_data) { 983 case X25_RESTART_LOCAL_PROCEDURE_ERROR: 984 pk_message (lcn, xcp, "restart: local procedure error"); 985 break; 986 987 case X25_RESTART_NETWORK_CONGESTION: 988 pk_message (lcn, xcp, "restart: network congestion"); 989 break; 990 991 case X25_RESTART_NETWORK_OPERATIONAL: 992 pk_message (lcn, xcp, "restart: network operational"); 993 break; 994 995 default: 996 pk_message (lcn, xcp, "restart: unknown cause"); 997 } 998 } 999 1000 #define MAXRESETCAUSE 7 1001 1002 int Reset_cause[] = { 1003 EXRESET, EXROUT, 0, EXRRPE, 0, EXRLPE, 0, EXRNCG 1004 }; 1005 1006 /* 1007 * A reset packet has arrived. Return the cause to the user. 1008 */ 1009 1010 pk_resetcause (pkp, xp) 1011 struct pkcb *pkp; 1012 register struct x25_packet *xp; 1013 { 1014 register struct pklcd *lcp = 1015 pkp -> pk_chan[LCN(xp)]; 1016 register int code = xp -> packet_data; 1017 1018 if (code > MAXRESETCAUSE) 1019 code = 7; /* EXRNCG */ 1020 1021 pk_message(LCN(xp), lcp -> lcd_pkp, "reset code 0x%x, diagnostic 0x%x", 1022 xp -> packet_data, 4[(u_char *)xp]); 1023 1024 if (lcp -> lcd_so) 1025 lcp -> lcd_so -> so_error = Reset_cause[code]; 1026 } 1027 1028 #define MAXCLEARCAUSE 25 1029 1030 int Clear_cause[] = { 1031 EXCLEAR, EXCBUSY, 0, EXCINV, 0, EXCNCG, 0, 1032 0, 0, EXCOUT, 0, EXCAB, 0, EXCNOB, 0, 0, 0, EXCRPE, 1033 0, EXCLPE, 0, 0, 0, 0, 0, EXCRRC 1034 }; 1035 1036 /* 1037 * A clear packet has arrived. Return the cause to the user. 1038 */ 1039 1040 pk_clearcause (pkp, xp) 1041 struct pkcb *pkp; 1042 register struct x25_packet *xp; 1043 { 1044 register struct pklcd *lcp = 1045 pkp -> pk_chan[LCN(xp)]; 1046 register int code = xp -> packet_data; 1047 1048 if (code > MAXCLEARCAUSE) 1049 code = 5; /* EXRNCG */ 1050 if (lcp -> lcd_so) 1051 lcp -> lcd_so -> so_error = Clear_cause[code]; 1052 } 1053 1054 char * 1055 format_ntn (xcp) 1056 register struct x25config *xcp; 1057 { 1058 1059 return (xcp -> xc_addr.x25_addr); 1060 } 1061 1062 /* VARARGS1 */ 1063 pk_message (lcn, xcp, fmt, a1, a2, a3, a4, a5, a6) 1064 struct x25config *xcp; 1065 char *fmt; 1066 { 1067 1068 if (lcn) 1069 if (!PQEMPTY) 1070 printf ("X.25(%s): lcn %d: ", format_ntn (xcp), lcn); 1071 else 1072 printf ("X.25: lcn %d: ", lcn); 1073 else 1074 if (!PQEMPTY) 1075 printf ("X.25(%s): ", format_ntn (xcp)); 1076 else 1077 printf ("X.25: "); 1078 1079 printf (fmt, a1, a2, a3, a4, a5, a6); 1080 printf ("\n"); 1081 } 1082 1083 pk_fragment (lcp, m0, qbit, mbit, wait) 1084 struct mbuf *m0; 1085 register struct pklcd *lcp; 1086 { 1087 register struct mbuf *m = m0; 1088 register struct x25_packet *xp; 1089 register struct sockbuf *sb; 1090 struct mbuf *head = 0, *next, **mp = &head, *m_split (); 1091 int totlen, psize = 1 << (lcp -> lcd_packetsize); 1092 1093 if (m == 0) 1094 return 0; 1095 if (m -> m_flags & M_PKTHDR == 0) 1096 panic ("pk_fragment"); 1097 totlen = m -> m_pkthdr.len; 1098 m -> m_act = 0; 1099 sb = lcp -> lcd_so ? &lcp -> lcd_so -> so_snd : & lcp -> lcd_sb; 1100 do { 1101 if (totlen > psize) { 1102 if ((next = m_split (m, psize, wait)) == 0) 1103 goto abort; 1104 totlen -= psize; 1105 } else 1106 next = 0; 1107 M_PREPEND(m, PKHEADERLN, wait); 1108 if (m == 0) 1109 goto abort; 1110 *mp = m; 1111 mp = & m -> m_act; 1112 *mp = 0; 1113 xp = mtod (m, struct x25_packet *); 1114 0[(char *)xp] = 0; 1115 if (qbit) 1116 X25SBITS(xp -> bits, q_bit, 1); 1117 if (lcp -> lcd_flags & X25_DBIT) 1118 X25SBITS(xp -> bits, d_bit, 1); 1119 X25SBITS(xp -> bits, fmt_identifier, 1); 1120 xp -> packet_type = X25_DATA; 1121 SET_LCN(xp, lcp -> lcd_lcn); 1122 if (next || (mbit && (totlen == psize || 1123 (lcp -> lcd_flags & X25_DBIT)))) 1124 SMBIT(xp, 1); 1125 } while (m = next); 1126 for (m = head; m; m = next) { 1127 next = m -> m_act; 1128 m -> m_act = 0; 1129 sbappendrecord (sb, m); 1130 } 1131 return 0; 1132 abort: 1133 if (wait) 1134 panic ("pk_fragment null mbuf after wait"); 1135 if (next) 1136 m_freem (next); 1137 for (m = head; m; m = next) { 1138 next = m -> m_act; 1139 m_freem (m); 1140 } 1141 return ENOBUFS; 1142 } 1143