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.26 (Berkeley) 06/05/93 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 static struct x25_ifaddr * 281 pk_ifwithaddr (sx) 282 struct sockaddr_x25 *sx; 283 { 284 struct ifnet *ifp; 285 struct ifaddr *ifa; 286 register struct x25_ifaddr *ia; 287 char *addr = sx -> x25_addr; 288 289 for (ifp = ifnet; ifp; ifp = ifp -> if_next) 290 for (ifa = ifp -> if_addrlist; ifa; ifa = ifa -> ifa_next) 291 if (ifa -> ifa_addr -> sa_family == AF_CCITT) { 292 ia = (struct x25_ifaddr *)ifa; 293 if (bcmp (addr, ia -> ia_xc.xc_addr.x25_addr, 294 16) == 0) 295 return (ia); 296 297 } 298 return ((struct x25_ifaddr *)0); 299 } 300 301 302 /* 303 * Bind a address and protocol value to a socket. The important 304 * part is the protocol value - the first four characters of the 305 * Call User Data field. 306 */ 307 308 #define XTRACTPKP(rt) ((rt) -> rt_flags & RTF_GATEWAY ? \ 309 ((rt) -> rt_llinfo ? \ 310 (struct pkcb *) ((struct rtentry *)((rt) -> rt_llinfo)) -> rt_llinfo : \ 311 (struct pkcb *) NULL) : \ 312 (struct pkcb *)((rt) -> rt_llinfo)) 313 314 pk_bind (lcp, nam) 315 struct pklcd *lcp; 316 struct mbuf *nam; 317 { 318 register struct pklcd *pp; 319 register struct sockaddr_x25 *sa; 320 321 if (nam == NULL) 322 return (EADDRNOTAVAIL); 323 if (lcp -> lcd_ceaddr) /* XXX */ 324 return (EADDRINUSE); 325 if (pk_checksockaddr (nam)) 326 return (EINVAL); 327 sa = mtod (nam, struct sockaddr_x25 *); 328 329 /* 330 * If the user wishes to accept calls only from a particular 331 * net (net != 0), make sure the net is known 332 */ 333 334 if (sa -> x25_addr[0]) { 335 if (!pk_ifwithaddr (sa)) 336 return (ENETUNREACH); 337 } else if (sa -> x25_net) { 338 if (!ifa_ifwithnet ((struct sockaddr *)sa)) 339 return (ENETUNREACH); 340 } 341 342 /* 343 * For ISO's sake permit default listeners, but only one such . . . 344 */ 345 for (pp = pk_listenhead; pp; pp = pp -> lcd_listen) { 346 register struct sockaddr_x25 *sa2 = pp -> lcd_ceaddr; 347 if ((sa2 -> x25_udlen == sa -> x25_udlen) && 348 (sa2 -> x25_udlen == 0 || 349 (bcmp (sa2 -> x25_udata, sa -> x25_udata, 350 min (sa2 -> x25_udlen, sa -> x25_udlen)) == 0))) 351 return (EADDRINUSE); 352 } 353 lcp -> lcd_laddr = *sa; 354 lcp -> lcd_ceaddr = &lcp -> lcd_laddr; 355 return (0); 356 } 357 358 /* 359 * Include a bound control block in the list of listeners. 360 */ 361 pk_listen (lcp) 362 register struct pklcd *lcp; 363 { 364 register struct pklcd **pp; 365 366 if (lcp -> lcd_ceaddr == 0) 367 return (EDESTADDRREQ); 368 369 lcp -> lcd_state = LISTEN; 370 /* 371 * Add default listener at end, any others at start. 372 */ 373 if (lcp -> lcd_ceaddr -> x25_udlen == 0) { 374 for (pp = &pk_listenhead; *pp; ) 375 pp = &((*pp) -> lcd_listen); 376 *pp = lcp; 377 } else { 378 lcp -> lcd_listen = pk_listenhead; 379 pk_listenhead = lcp; 380 } 381 return (0); 382 } 383 /* 384 * Include a listening control block for the benefit of other protocols. 385 */ 386 pk_protolisten (spi, spilen, callee) 387 int (*callee) (); 388 { 389 register struct pklcd *lcp = pk_attach ((struct socket *)0); 390 register struct mbuf *nam; 391 register struct sockaddr_x25 *sa; 392 int error = ENOBUFS; 393 394 if (lcp) { 395 if (nam = m_getclr (MT_SONAME, M_DONTWAIT)) { 396 sa = mtod (nam, struct sockaddr_x25 *); 397 sa -> x25_family = AF_CCITT; 398 sa -> x25_len = nam -> m_len = sizeof (*sa); 399 sa -> x25_udlen = spilen; 400 sa -> x25_udata[0] = spi; 401 lcp -> lcd_upper = callee; 402 lcp -> lcd_flags = X25_MBS_HOLD; 403 if ((error = pk_bind (lcp, nam)) == 0) 404 error = pk_listen (lcp); 405 (void) m_free (nam); 406 } 407 if (error) 408 pk_freelcd (lcp); 409 } 410 return error; /* Hopefully Zero !*/ 411 } 412 413 /* 414 * Associate a logical channel descriptor with a network. 415 * Fill in the default network specific parameters and then 416 * set any parameters explicitly specified by the user or 417 * by the remote DTE. 418 */ 419 420 pk_assoc (pkp, lcp, sa) 421 register struct pkcb *pkp; 422 register struct pklcd *lcp; 423 register struct sockaddr_x25 *sa; 424 { 425 426 lcp -> lcd_pkp = pkp; 427 lcp -> lcd_packetsize = pkp -> pk_xcp -> xc_psize; 428 lcp -> lcd_windowsize = pkp -> pk_xcp -> xc_pwsize; 429 lcp -> lcd_rsn = MODULUS - 1; 430 pkp -> pk_chan[lcp -> lcd_lcn] = lcp; 431 432 if (sa -> x25_opts.op_psize) 433 lcp -> lcd_packetsize = sa -> x25_opts.op_psize; 434 else 435 sa -> x25_opts.op_psize = lcp -> lcd_packetsize; 436 if (sa -> x25_opts.op_wsize) 437 lcp -> lcd_windowsize = sa -> x25_opts.op_wsize; 438 else 439 sa -> x25_opts.op_wsize = lcp -> lcd_windowsize; 440 sa -> x25_net = pkp -> pk_xcp -> xc_addr.x25_net; 441 lcp -> lcd_flags |= sa -> x25_opts.op_flags; 442 lcp -> lcd_stime = time.tv_sec; 443 } 444 445 pk_connect (lcp, sa) 446 register struct pklcd *lcp; 447 register struct sockaddr_x25 *sa; 448 { 449 register struct pkcb *pkp; 450 register struct rtentry *rt; 451 register struct rtentry *nrt; 452 453 struct rtentry *npaidb_enter (); 454 struct pkcb *pk_newlink (); 455 456 if (sa -> x25_addr[0] == '\0') 457 return (EDESTADDRREQ); 458 459 /* 460 * Is the destination address known? 461 */ 462 if (!(rt = rtalloc1 ((struct sockaddr *)sa, 1))) 463 return (ENETUNREACH); 464 465 if (!(pkp = XTRACTPKP(rt))) 466 pkp = pk_newlink ((struct x25_ifaddr *) (rt -> rt_ifa), 467 (caddr_t) 0); 468 469 /* 470 * Have we entered the LLC address? 471 */ 472 if (nrt = npaidb_enter (rt -> rt_gateway, rt_key (rt), rt, 0)) 473 pkp -> pk_llrt = nrt; 474 475 /* 476 * Have we allocated an LLC2 link yet? 477 */ 478 if (pkp -> pk_llnext == (caddr_t)0 && pkp -> pk_llctlinput) { 479 struct dll_ctlinfo ctlinfo; 480 481 ctlinfo.dlcti_rt = rt; 482 ctlinfo.dlcti_pcb = (caddr_t) pkp; 483 ctlinfo.dlcti_conf = 484 (struct dllconfig *) (&((struct x25_ifaddr *)(rt -> rt_ifa)) -> ia_xc); 485 pkp -> pk_llnext = 486 (pkp -> pk_llctlinput) (PRC_CONNECT_REQUEST, 0, &ctlinfo); 487 } 488 489 if (pkp -> pk_state != DTE_READY && pkp -> pk_state != DTE_WAITING) 490 return (ENETDOWN); 491 if ((lcp -> lcd_lcn = pk_getlcn (pkp)) == 0) 492 return (EMFILE); 493 494 lcp -> lcd_faddr = *sa; 495 lcp -> lcd_ceaddr = & lcp -> lcd_faddr; 496 pk_assoc (pkp, lcp, lcp -> lcd_ceaddr); 497 498 /* 499 * If the link is not up yet, initiate an X.25 RESTART 500 */ 501 if (pkp -> pk_state == DTE_WAITING) { 502 pkp -> pk_dxerole |= DTE_CONNECTPENDING; 503 pk_ctlinput (PRC_LINKUP, (struct sockaddr *)0, pkp); 504 if (lcp -> lcd_so) 505 soisconnecting (lcp -> lcd_so); 506 return 0; 507 } 508 509 if (lcp -> lcd_so) 510 soisconnecting (lcp -> lcd_so); 511 lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL); 512 pk_callrequest (lcp, lcp -> lcd_ceaddr, pkp -> pk_xcp); 513 return (*pkp -> pk_ia -> ia_start) (lcp); 514 } 515 516 /* 517 * Complete all pending X.25 call requests --- this gets called after 518 * the X.25 link has been restarted. 519 */ 520 #define RESHUFFLELCN(maxlcn, lcn) ((maxlcn) - (lcn) + 1) 521 522 pk_callcomplete (pkp) 523 register struct pkcb *pkp; 524 { 525 register struct pklcd *lcp; 526 register int i; 527 register int ni; 528 529 530 if (pkp -> pk_dxerole & DTE_CONNECTPENDING) 531 pkp -> pk_dxerole &= ~DTE_CONNECTPENDING; 532 else return; 533 534 if (pkp -> pk_chan == 0) 535 return; 536 537 /* 538 * We pretended to be a DTE for allocating lcns, if 539 * it turns out that we are in reality performing as a 540 * DCE we need to reshuffle the lcps. 541 * 542 * /+---------------+-------- - 543 * / | a (maxlcn-1) | \ 544 * / +---------------+ \ 545 * +--- * | b (maxlcn-2) | \ 546 * | \ +---------------+ \ 547 * r | \ | c (maxlcn-3) | \ 548 * e | \+---------------+ | 549 * s | | . | 550 * h | | . | m 551 * u | | . | a 552 * f | | . | x 553 * f | | . | l 554 * l | /+---------------+ | c 555 * e | / | c' ( 3 ) | | n 556 * | / +---------------+ | 557 * +--> * | b' ( 2 ) | / 558 * \ +---------------+ / 559 * \ | a' ( 1 ) | / 560 * \+---------------+ / 561 * | 0 | / 562 * +---------------+-------- - 563 * 564 */ 565 if (pkp -> pk_dxerole & DTE_PLAYDCE) { 566 /* Sigh, reshuffle it */ 567 for (i = pkp -> pk_maxlcn; i > 0; --i) 568 if (pkp -> pk_chan[i]) { 569 ni = RESHUFFLELCN(pkp -> pk_maxlcn, i); 570 pkp -> pk_chan[ni] = pkp -> pk_chan[i]; 571 pkp -> pk_chan[i] = NULL; 572 pkp -> pk_chan[ni] -> lcd_lcn = ni; 573 } 574 } 575 576 for (i = 1; i <= pkp -> pk_maxlcn; ++i) 577 if ((lcp = pkp -> pk_chan[i]) != NULL) { 578 /* if (lcp -> lcd_so) 579 soisconnecting (lcp -> lcd_so); */ 580 lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL); 581 pk_callrequest (lcp, lcp -> lcd_ceaddr, pkp -> pk_xcp); 582 (*pkp -> pk_ia -> ia_start) (lcp); 583 } 584 } 585 586 struct bcdinfo { 587 octet *cp; 588 unsigned posn; 589 }; 590 /* 591 * Build the rest of the CALL REQUEST packet. Fill in calling 592 * address, facilities fields and the user data field. 593 */ 594 595 pk_callrequest (lcp, sa, xcp) 596 struct pklcd *lcp; 597 register struct sockaddr_x25 *sa; 598 register struct x25config *xcp; 599 { 600 register struct x25_calladdr *a; 601 register struct mbuf *m = lcp -> lcd_template; 602 register struct x25_packet *xp = mtod (m, struct x25_packet *); 603 struct bcdinfo b; 604 605 if (lcp -> lcd_flags & X25_DBIT) 606 X25SBITS(xp -> bits, d_bit, 1); 607 a = (struct x25_calladdr *) &xp -> packet_data; 608 b.cp = (octet *) a -> address_field; 609 b.posn = 0; 610 X25SBITS(a -> addrlens, called_addrlen, to_bcd (&b, sa, xcp)); 611 X25SBITS(a -> addrlens, calling_addrlen, to_bcd (&b, &xcp -> xc_addr, xcp)); 612 if (b.posn & 0x01) 613 *b.cp++ &= 0xf0; 614 m -> m_pkthdr.len = m -> m_len += b.cp - (octet *) a; 615 616 if (lcp -> lcd_facilities) { 617 m -> m_pkthdr.len += 618 (m -> m_next = lcp -> lcd_facilities) -> m_pkthdr.len; 619 lcp -> lcd_facilities = 0; 620 } else 621 pk_build_facilities (m, sa, (int)xcp -> xc_type); 622 623 m_copyback (m, m -> m_pkthdr.len, sa -> x25_udlen, sa -> x25_udata); 624 } 625 626 pk_build_facilities (m, sa, type) 627 register struct mbuf *m; 628 struct sockaddr_x25 *sa; 629 { 630 register octet *cp; 631 register octet *fcp; 632 register int revcharge; 633 634 cp = mtod (m, octet *) + m -> m_len; 635 fcp = cp + 1; 636 revcharge = sa -> x25_opts.op_flags & X25_REVERSE_CHARGE ? 1 : 0; 637 /* 638 * This is specific to Datapac X.25(1976) DTEs. International 639 * calls must have the "hi priority" bit on. 640 */ 641 if (type == X25_1976 && sa -> x25_opts.op_psize == X25_PS128) 642 revcharge |= 02; 643 if (revcharge) { 644 *fcp++ = FACILITIES_REVERSE_CHARGE; 645 *fcp++ = revcharge; 646 } 647 switch (type) { 648 case X25_1980: 649 case X25_1984: 650 *fcp++ = FACILITIES_PACKETSIZE; 651 *fcp++ = sa -> x25_opts.op_psize; 652 *fcp++ = sa -> x25_opts.op_psize; 653 654 *fcp++ = FACILITIES_WINDOWSIZE; 655 *fcp++ = sa -> x25_opts.op_wsize; 656 *fcp++ = sa -> x25_opts.op_wsize; 657 } 658 *cp = fcp - cp - 1; 659 m -> m_pkthdr.len = (m -> m_len += *cp + 1); 660 } 661 662 to_bcd (b, sa, xcp) 663 register struct bcdinfo *b; 664 struct sockaddr_x25 *sa; 665 register struct x25config *xcp; 666 { 667 register char *x = sa -> x25_addr; 668 unsigned start = b -> posn; 669 /* 670 * The nodnic and prepnd0 stuff looks tedious, 671 * but it does allow full X.121 addresses to be used, 672 * which is handy for routing info (& OSI type 37 addresses). 673 */ 674 if (xcp -> xc_addr.x25_net && (xcp -> xc_nodnic || xcp -> xc_prepnd0)) { 675 char dnicname[sizeof (long) * NBBY/3 + 2]; 676 register char *p = dnicname; 677 678 sprintf (p, "%d", xcp -> xc_addr.x25_net & 0x7fff); 679 for (; *p; p++) /* *p == 0 means dnic matched */ 680 if ((*p ^ *x++) & 0x0f) 681 break; 682 if (*p || xcp -> xc_nodnic == 0) 683 x = sa -> x25_addr; 684 if (*p && xcp -> xc_prepnd0) { 685 if ((b -> posn)++ & 0x01) 686 *(b -> cp)++; 687 else 688 *(b -> cp) = 0; 689 } 690 } 691 while (*x) 692 if ((b -> posn)++ & 0x01) 693 *(b -> cp)++ |= *x++ & 0x0F; 694 else 695 *(b -> cp) = *x++ << 4; 696 return ((b -> posn) - start); 697 } 698 699 /* 700 * This routine gets the first available logical channel number. The 701 * search is 702 * - from the highest number to lowest number if playing DTE, and 703 * - from lowest to highest number if playing DCE. 704 */ 705 706 pk_getlcn (pkp) 707 register struct pkcb *pkp; 708 { 709 register int i; 710 711 if (pkp -> pk_chan == 0) 712 return (0); 713 if ( pkp -> pk_dxerole & DTE_PLAYDCE ) { 714 for (i = 1; i <= pkp -> pk_maxlcn; ++i) 715 if (pkp -> pk_chan[i] == NULL) 716 break; 717 } else { 718 for (i = pkp -> pk_maxlcn; i > 0; --i) 719 if (pkp -> pk_chan[i] == NULL) 720 break; 721 } 722 i = ( i > pkp -> pk_maxlcn ? 0 : i ); 723 return (i); 724 } 725 726 /* 727 * This procedure sends a CLEAR request packet. The lc state is 728 * set to "SENT_CLEAR". 729 */ 730 731 pk_clear (lcp, diagnostic, abortive) 732 register struct pklcd *lcp; 733 { 734 register struct mbuf *m = pk_template (lcp -> lcd_lcn, X25_CLEAR); 735 736 m -> m_len += 2; 737 m -> m_pkthdr.len += 2; 738 mtod (m, struct x25_packet *) -> packet_data = 0; 739 mtod (m, octet *)[4] = diagnostic; 740 if (lcp -> lcd_facilities) { 741 m -> m_next = lcp -> lcd_facilities; 742 m -> m_pkthdr.len += m -> m_next -> m_len; 743 lcp -> lcd_facilities = 0; 744 } 745 if (abortive) 746 lcp -> lcd_template = m; 747 else { 748 struct socket *so = lcp -> lcd_so; 749 struct sockbuf *sb = so ? & so -> so_snd : & lcp -> lcd_sb; 750 sbappendrecord (sb, m); 751 } 752 pk_output (lcp); 753 754 } 755 756 /* 757 * This procedure generates RNR's or RR's to inhibit or enable 758 * inward data flow, if the current state changes (blocked ==> open or 759 * vice versa), or if forced to generate one. One forces RNR's to ack data. 760 */ 761 pk_flowcontrol (lcp, inhibit, forced) 762 register struct pklcd *lcp; 763 { 764 inhibit = (inhibit != 0); 765 if (lcp == 0 || lcp -> lcd_state != DATA_TRANSFER || 766 (forced == 0 && lcp -> lcd_rxrnr_condition == inhibit)) 767 return; 768 lcp -> lcd_rxrnr_condition = inhibit; 769 lcp -> lcd_template = 770 pk_template (lcp -> lcd_lcn, inhibit ? X25_RNR : X25_RR); 771 pk_output (lcp); 772 } 773 774 /* 775 * This procedure sends a RESET request packet. It re-intializes 776 * virtual circuit. 777 */ 778 779 static 780 pk_reset (lcp, diagnostic) 781 register struct pklcd *lcp; 782 { 783 register struct mbuf *m; 784 register struct socket *so = lcp -> lcd_so; 785 786 if (lcp -> lcd_state != DATA_TRANSFER) 787 return; 788 789 if (so) 790 so -> so_error = ECONNRESET; 791 lcp -> lcd_reset_condition = TRUE; 792 793 /* Reset all the control variables for the channel. */ 794 pk_flush (lcp); 795 lcp -> lcd_window_condition = lcp -> lcd_rnr_condition = 796 lcp -> lcd_intrconf_pending = FALSE; 797 lcp -> lcd_rsn = MODULUS - 1; 798 lcp -> lcd_ssn = 0; 799 lcp -> lcd_output_window = lcp -> lcd_input_window = 800 lcp -> lcd_last_transmitted_pr = 0; 801 m = lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET); 802 m -> m_pkthdr.len = m -> m_len += 2; 803 mtod (m, struct x25_packet *) -> packet_data = 0; 804 mtod (m, octet *)[4] = diagnostic; 805 pk_output (lcp); 806 807 } 808 809 /* 810 * This procedure frees all data queued for output or delivery on a 811 * virtual circuit. 812 */ 813 814 pk_flush (lcp) 815 register struct pklcd *lcp; 816 { 817 register struct socket *so; 818 819 if (lcp -> lcd_template) 820 m_freem (lcp -> lcd_template); 821 822 if (lcp -> lcd_cps) { 823 m_freem (lcp -> lcd_cps); 824 lcp -> lcd_cps = 0; 825 } 826 if (lcp -> lcd_facilities) { 827 m_freem (lcp -> lcd_facilities); 828 lcp -> lcd_facilities = 0; 829 } 830 if (so = lcp -> lcd_so) 831 sbflush (&so -> so_snd); 832 else 833 sbflush (&lcp -> lcd_sb); 834 } 835 836 /* 837 * This procedure handles all local protocol procedure errors. 838 */ 839 840 pk_procerror (error, lcp, errstr, diagnostic) 841 register struct pklcd *lcp; 842 char *errstr; 843 { 844 845 pk_message (lcp -> lcd_lcn, lcp -> lcd_pkp -> pk_xcp, errstr); 846 847 switch (error) { 848 case CLEAR: 849 if (lcp -> lcd_so) { 850 lcp -> lcd_so -> so_error = ECONNABORTED; 851 soisdisconnecting (lcp -> lcd_so); 852 } 853 pk_clear (lcp, diagnostic, 1); 854 break; 855 856 case RESET: 857 pk_reset (lcp, diagnostic); 858 } 859 } 860 861 /* 862 * This procedure is called during the DATA TRANSFER state to check 863 * and process the P(R) values received in the DATA, RR OR RNR 864 * packets. 865 */ 866 867 pk_ack (lcp, pr) 868 struct pklcd *lcp; 869 unsigned pr; 870 { 871 register struct socket *so = lcp -> lcd_so; 872 873 if (lcp -> lcd_output_window == pr) 874 return (PACKET_OK); 875 if (lcp -> lcd_output_window < lcp -> lcd_ssn) { 876 if (pr < lcp -> lcd_output_window || pr > lcp -> lcd_ssn) { 877 pk_procerror (RESET, lcp, 878 "p(r) flow control error", 2); 879 return (ERROR_PACKET); 880 } 881 } 882 else { 883 if (pr < lcp -> lcd_output_window && pr > lcp -> lcd_ssn) { 884 pk_procerror (RESET, lcp, 885 "p(r) flow control error #2", 2); 886 return (ERROR_PACKET); 887 } 888 } 889 890 lcp -> lcd_output_window = pr; /* Rotate window. */ 891 if (lcp -> lcd_window_condition == TRUE) 892 lcp -> lcd_window_condition = FALSE; 893 894 if (so && ((so -> so_snd.sb_flags & SB_WAIT) || 895 (so -> so_snd.sb_flags & SB_NOTIFY))) 896 sowwakeup (so); 897 898 return (PACKET_OK); 899 } 900 901 /* 902 * This procedure decodes the X.25 level 3 packet returning a 903 * code to be used in switchs or arrays. 904 */ 905 906 pk_decode (xp) 907 register struct x25_packet *xp; 908 { 909 register int type; 910 911 if (X25GBITS(xp -> bits, fmt_identifier) != 1) 912 return (INVALID_PACKET); 913 #ifdef ancient_history 914 /* 915 * Make sure that the logical channel group number is 0. 916 * This restriction may be removed at some later date. 917 */ 918 if (xp -> lc_group_number != 0) 919 return (INVALID_PACKET); 920 #endif 921 /* 922 * Test for data packet first. 923 */ 924 if (!(xp -> packet_type & DATA_PACKET_DESIGNATOR)) 925 return (DATA); 926 927 /* 928 * Test if flow control packet (RR or RNR). 929 */ 930 if (!(xp -> packet_type & RR_OR_RNR_PACKET_DESIGNATOR)) 931 switch (xp -> packet_type & 0x1f) { 932 case X25_RR: 933 return (RR); 934 case X25_RNR: 935 return (RNR); 936 case X25_REJECT: 937 return (REJECT); 938 } 939 940 /* 941 * Determine the rest of the packet types. 942 */ 943 switch (xp -> packet_type) { 944 case X25_CALL: 945 type = CALL; 946 break; 947 948 case X25_CALL_ACCEPTED: 949 type = CALL_ACCEPTED; 950 break; 951 952 case X25_CLEAR: 953 type = CLEAR; 954 break; 955 956 case X25_CLEAR_CONFIRM: 957 type = CLEAR_CONF; 958 break; 959 960 case X25_INTERRUPT: 961 type = INTERRUPT; 962 break; 963 964 case X25_INTERRUPT_CONFIRM: 965 type = INTERRUPT_CONF; 966 break; 967 968 case X25_RESET: 969 type = RESET; 970 break; 971 972 case X25_RESET_CONFIRM: 973 type = RESET_CONF; 974 break; 975 976 case X25_RESTART: 977 type = RESTART; 978 break; 979 980 case X25_RESTART_CONFIRM: 981 type = RESTART_CONF; 982 break; 983 984 case X25_DIAGNOSTIC: 985 type = DIAG_TYPE; 986 break; 987 988 default: 989 type = INVALID_PACKET; 990 } 991 return (type); 992 } 993 994 /* 995 * A restart packet has been received. Print out the reason 996 * for the restart. 997 */ 998 999 pk_restartcause (pkp, xp) 1000 struct pkcb *pkp; 1001 register struct x25_packet *xp; 1002 { 1003 register struct x25config *xcp = pkp -> pk_xcp; 1004 register int lcn = LCN(xp); 1005 1006 switch (xp -> packet_data) { 1007 case X25_RESTART_LOCAL_PROCEDURE_ERROR: 1008 pk_message (lcn, xcp, "restart: local procedure error"); 1009 break; 1010 1011 case X25_RESTART_NETWORK_CONGESTION: 1012 pk_message (lcn, xcp, "restart: network congestion"); 1013 break; 1014 1015 case X25_RESTART_NETWORK_OPERATIONAL: 1016 pk_message (lcn, xcp, "restart: network operational"); 1017 break; 1018 1019 default: 1020 pk_message (lcn, xcp, "restart: unknown cause"); 1021 } 1022 } 1023 1024 #define MAXRESETCAUSE 7 1025 1026 int Reset_cause[] = { 1027 EXRESET, EXROUT, 0, EXRRPE, 0, EXRLPE, 0, EXRNCG 1028 }; 1029 1030 /* 1031 * A reset packet has arrived. Return the cause to the user. 1032 */ 1033 1034 pk_resetcause (pkp, xp) 1035 struct pkcb *pkp; 1036 register struct x25_packet *xp; 1037 { 1038 register struct pklcd *lcp = 1039 pkp -> pk_chan[LCN(xp)]; 1040 register int code = xp -> packet_data; 1041 1042 if (code > MAXRESETCAUSE) 1043 code = 7; /* EXRNCG */ 1044 1045 pk_message (LCN(xp), lcp -> lcd_pkp, "reset code 0x%x, diagnostic 0x%x", 1046 xp -> packet_data, 4[(u_char *)xp]); 1047 1048 if (lcp -> lcd_so) 1049 lcp -> lcd_so -> so_error = Reset_cause[code]; 1050 } 1051 1052 #define MAXCLEARCAUSE 25 1053 1054 int Clear_cause[] = { 1055 EXCLEAR, EXCBUSY, 0, EXCINV, 0, EXCNCG, 0, 1056 0, 0, EXCOUT, 0, EXCAB, 0, EXCNOB, 0, 0, 0, EXCRPE, 1057 0, EXCLPE, 0, 0, 0, 0, 0, EXCRRC 1058 }; 1059 1060 /* 1061 * A clear packet has arrived. Return the cause to the user. 1062 */ 1063 1064 pk_clearcause (pkp, xp) 1065 struct pkcb *pkp; 1066 register struct x25_packet *xp; 1067 { 1068 register struct pklcd *lcp = 1069 pkp -> pk_chan[LCN(xp)]; 1070 register int code = xp -> packet_data; 1071 1072 if (code > MAXCLEARCAUSE) 1073 code = 5; /* EXRNCG */ 1074 if (lcp -> lcd_so) 1075 lcp -> lcd_so -> so_error = Clear_cause[code]; 1076 } 1077 1078 char * 1079 format_ntn (xcp) 1080 register struct x25config *xcp; 1081 { 1082 1083 return (xcp -> xc_addr.x25_addr); 1084 } 1085 1086 /* VARARGS1 */ 1087 pk_message (lcn, xcp, fmt, a1, a2, a3, a4, a5, a6) 1088 struct x25config *xcp; 1089 char *fmt; 1090 { 1091 1092 if (lcn) 1093 if (!PQEMPTY) 1094 printf ("X.25(%s): lcn %d: ", format_ntn (xcp), lcn); 1095 else 1096 printf ("X.25: lcn %d: ", lcn); 1097 else 1098 if (!PQEMPTY) 1099 printf ("X.25(%s): ", format_ntn (xcp)); 1100 else 1101 printf ("X.25: "); 1102 1103 printf (fmt, a1, a2, a3, a4, a5, a6); 1104 printf ("\n"); 1105 } 1106 1107 pk_fragment (lcp, m0, qbit, mbit, wait) 1108 struct mbuf *m0; 1109 register struct pklcd *lcp; 1110 { 1111 register struct mbuf *m = m0; 1112 register struct x25_packet *xp; 1113 register struct sockbuf *sb; 1114 struct mbuf *head = 0, *next, **mp = &head, *m_split (); 1115 int totlen, psize = 1 << (lcp -> lcd_packetsize); 1116 1117 if (m == 0) 1118 return 0; 1119 if (m -> m_flags & M_PKTHDR == 0) 1120 panic ("pk_fragment"); 1121 totlen = m -> m_pkthdr.len; 1122 m -> m_act = 0; 1123 sb = lcp -> lcd_so ? &lcp -> lcd_so -> so_snd : & lcp -> lcd_sb; 1124 do { 1125 if (totlen > psize) { 1126 if ((next = m_split (m, psize, wait)) == 0) 1127 goto abort; 1128 totlen -= psize; 1129 } else 1130 next = 0; 1131 M_PREPEND(m, PKHEADERLN, wait); 1132 if (m == 0) 1133 goto abort; 1134 *mp = m; 1135 mp = & m -> m_act; 1136 *mp = 0; 1137 xp = mtod (m, struct x25_packet *); 1138 0[(char *)xp] = 0; 1139 if (qbit) 1140 X25SBITS(xp -> bits, q_bit, 1); 1141 if (lcp -> lcd_flags & X25_DBIT) 1142 X25SBITS(xp -> bits, d_bit, 1); 1143 X25SBITS(xp -> bits, fmt_identifier, 1); 1144 xp -> packet_type = X25_DATA; 1145 SET_LCN(xp, lcp -> lcd_lcn); 1146 if (next || (mbit && (totlen == psize || 1147 (lcp -> lcd_flags & X25_DBIT)))) 1148 SMBIT(xp, 1); 1149 } while (m = next); 1150 for (m = head; m; m = next) { 1151 next = m -> m_act; 1152 m -> m_act = 0; 1153 sbappendrecord (sb, m); 1154 } 1155 return 0; 1156 abort: 1157 if (wait) 1158 panic ("pk_fragment null mbuf after wait"); 1159 if (next) 1160 m_freem (next); 1161 for (m = head; m; m = next) { 1162 next = m -> m_act; 1163 m_freem (m); 1164 } 1165 return ENOBUFS; 1166 } 1167