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