141709Ssklower /* 241709Ssklower * Copyright (c) University of British Columbia, 1984 357024Ssklower * Copyright (C) Computer Science Department IV, 457024Ssklower * University of Erlangen-Nuremberg, Germany, 1992 557024Ssklower * Copyright (c) 1991, 1992 The Regents of the University of California. 641709Ssklower * All rights reserved. 741709Ssklower * 857024Ssklower * This code is derived from software contributed to Berkeley by the 957024Ssklower * Laboratory for Computation Vision and the Computer Science Department 1057024Ssklower * of the the University of British Columbia and the Computer Science 1157024Ssklower * Department (IV) of the University of Erlangen-Nuremberg, Germany. 1241709Ssklower * 1341709Ssklower * %sccs.include.redist.c% 1441709Ssklower * 15*57957Ssklower * @(#)pk_input.c 7.20 (Berkeley) 02/12/93 1641709Ssklower */ 1741591Ssklower 1856530Sbostic #include <sys/param.h> 1956530Sbostic #include <sys/systm.h> 2056530Sbostic #include <sys/mbuf.h> 2156530Sbostic #include <sys/socket.h> 2256530Sbostic #include <sys/protosw.h> 2356530Sbostic #include <sys/socketvar.h> 2456530Sbostic #include <sys/errno.h> 2541591Ssklower 2656530Sbostic #include <net/if.h> 2757032Ssklower #include <net/if_dl.h> 2857032Ssklower #include <net/if_llc.h> 2957032Ssklower #include <net/route.h> 3041591Ssklower 3157024Ssklower #include <netccitt/dll.h> 3256530Sbostic #include <netccitt/x25.h> 3356530Sbostic #include <netccitt/pk.h> 3456530Sbostic #include <netccitt/pk_var.h> 3557024Ssklower #include <netccitt/llc_var.h> 3641591Ssklower 3757024Ssklower struct pkcb_q pkcb_q = {&pkcb_q, &pkcb_q}; 3857024Ssklower 3957024Ssklower /* 4057024Ssklower * ccittintr() is the generic interrupt handler for HDLC, LLC2, and X.25. This 4157024Ssklower * allows to have kernel running X.25 but no HDLC or LLC2 or both (in case we 4257024Ssklower * employ boards that do all the stuff themselves, e.g. ADAX X.25 or TPS ISDN.) 4357024Ssklower */ 4457024Ssklower void 45*57957Ssklower ccittintr () 4657024Ssklower { 4757024Ssklower extern struct ifqueue pkintrq; 4857024Ssklower extern struct ifqueue hdintrq; 4957024Ssklower extern struct ifqueue llcintrq; 5057024Ssklower 5157024Ssklower #ifdef HDLC 5257024Ssklower if (hdintrq.ifq_len) 5357024Ssklower hdintr (); 5457024Ssklower #endif 5557024Ssklower #ifdef LLC 5657024Ssklower if (llcintrq.ifq_len) 5757024Ssklower llcintr (); 5857024Ssklower #endif 5957024Ssklower if (pkintrq.ifq_len) 6057024Ssklower pkintr (); 6157024Ssklower } 6257024Ssklower 6349930Ssklower struct pkcb * 6449930Ssklower pk_newlink (ia, llnext) 6549930Ssklower struct x25_ifaddr *ia; 6649930Ssklower caddr_t llnext; 6749930Ssklower { 68*57957Ssklower register struct x25config *xcp = &ia -> ia_xc; 6949930Ssklower register struct pkcb *pkp; 7049930Ssklower register struct pklcd *lcp; 7149930Ssklower register struct protosw *pp; 7249930Ssklower unsigned size; 7349930Ssklower 74*57957Ssklower pp = pffindproto (AF_CCITT, (int) xcp -> xc_lproto, 0); 7549930Ssklower if (pp == 0 || pp -> pr_output == 0) { 7649930Ssklower pk_message (0, xcp, "link level protosw error"); 7749930Ssklower return ((struct pkcb *)0); 7849930Ssklower } 7949930Ssklower /* 8049930Ssklower * Allocate a network control block structure 8149930Ssklower */ 8249930Ssklower size = sizeof (struct pkcb); 83*57957Ssklower pkp = (struct pkcb *) malloc (size, M_PCB, M_WAITOK); 8449930Ssklower if (pkp == 0) 8549930Ssklower return ((struct pkcb *)0); 86*57957Ssklower bzero ((caddr_t) pkp, size); 8749930Ssklower pkp -> pk_lloutput = pp -> pr_output; 88*57957Ssklower pkp -> pk_llctlinput = (caddr_t (*)()) pp -> pr_ctlinput; 8949930Ssklower pkp -> pk_xcp = xcp; 9049930Ssklower pkp -> pk_ia = ia; 9149930Ssklower pkp -> pk_state = DTE_WAITING; 9249930Ssklower pkp -> pk_llnext = llnext; 93*57957Ssklower insque (pkp, &pkcb_q); 9449930Ssklower 9549930Ssklower /* 9649930Ssklower * set defaults 9749930Ssklower */ 9849930Ssklower 9949930Ssklower if (xcp -> xc_pwsize == 0) 10049930Ssklower xcp -> xc_pwsize = DEFAULT_WINDOW_SIZE; 10149930Ssklower if (xcp -> xc_psize == 0) 10249930Ssklower xcp -> xc_psize = X25_PS128; 10349930Ssklower /* 10449930Ssklower * Allocate logical channel descriptor vector 10549930Ssklower */ 10649930Ssklower 107*57957Ssklower (void) pk_resize (pkp); 10849930Ssklower return (pkp); 10949930Ssklower } 11049930Ssklower 11157024Ssklower 11257024Ssklower pk_dellink (pkp) 11357024Ssklower register struct pkcb *pkp; 11457024Ssklower { 11557024Ssklower register int i; 11657024Ssklower register struct protosw *pp; 11757024Ssklower 11857024Ssklower /* 11957024Ssklower * Essentially we have the choice to 12057024Ssklower * (a) go ahead and let the route be deleted and 12157024Ssklower * leave the pkcb associated with that route 12257024Ssklower * as it is, i.e. the connections stay open 12357024Ssklower * (b) do a pk_disconnect() on all channels associated 12457024Ssklower * with the route via the pkcb and then proceed. 12557024Ssklower * 12657024Ssklower * For the time being we stick with (b) 12757024Ssklower */ 12857024Ssklower 129*57957Ssklower for (i = 1; i < pkp -> pk_maxlcn; ++i) 130*57957Ssklower if (pkp -> pk_chan[i]) 131*57957Ssklower pk_disconnect (pkp -> pk_chan[i]); 13257024Ssklower 13357024Ssklower /* 13457024Ssklower * Free the pkcb 13557024Ssklower */ 13657024Ssklower 13757024Ssklower /* 13857024Ssklower * First find the protoswitch to get hold of the link level 13957024Ssklower * protocol to be notified that the packet level entity is 14057024Ssklower * dissolving ... 14157024Ssklower */ 142*57957Ssklower pp = pffindproto (AF_CCITT, (int) pkp -> pk_xcp -> xc_lproto, 0); 14357024Ssklower if (pp == 0 || pp -> pr_output == 0) { 14457024Ssklower pk_message (0, pkp -> pk_xcp, "link level protosw error"); 145*57957Ssklower return (EPROTONOSUPPORT); 14657024Ssklower } 14757024Ssklower 14857024Ssklower pkp -> pk_refcount--; 14957024Ssklower if (!pkp -> pk_refcount) { 15057024Ssklower struct dll_ctlinfo ctlinfo; 15157024Ssklower 152*57957Ssklower remque (pkp); 15357024Ssklower if (pkp -> pk_rt -> rt_llinfo == (caddr_t) pkp) 15457024Ssklower pkp -> pk_rt -> rt_llinfo = (caddr_t) NULL; 15557024Ssklower 15657024Ssklower /* 15757024Ssklower * Tell the link level that the pkcb is dissolving 15857024Ssklower */ 15957024Ssklower if (pp -> pr_ctlinput && pkp -> pk_llnext) { 16057024Ssklower ctlinfo.dlcti_pcb = pkp -> pk_llnext; 16157024Ssklower ctlinfo.dlcti_rt = pkp -> pk_rt; 16257024Ssklower (pp -> pr_ctlinput)(PRC_DISCONNECT_REQUEST, 16357024Ssklower pkp -> pk_xcp, &ctlinfo); 16457024Ssklower } 165*57957Ssklower free ((caddr_t) pkp -> pk_chan, M_IFADDR); 166*57957Ssklower free ((caddr_t) pkp, M_PCB); 16757024Ssklower } 16857024Ssklower 16957024Ssklower return (0); 17057024Ssklower } 17157024Ssklower 17257024Ssklower 17349930Ssklower pk_resize (pkp) 17449930Ssklower register struct pkcb *pkp; 17549930Ssklower { 17649930Ssklower struct pklcd *dev_lcp = 0; 17749930Ssklower struct x25config *xcp = pkp -> pk_xcp; 17849930Ssklower if (pkp -> pk_chan && 17949930Ssklower (pkp -> pk_maxlcn != xcp -> xc_maxlcn)) { 18049930Ssklower pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION); 18149930Ssklower dev_lcp = pkp -> pk_chan[0]; 182*57957Ssklower free ((caddr_t) pkp -> pk_chan, M_IFADDR); 18349930Ssklower pkp -> pk_chan = 0; 18449930Ssklower } 18549930Ssklower if (pkp -> pk_chan == 0) { 18649930Ssklower unsigned size; 18749930Ssklower pkp -> pk_maxlcn = xcp -> xc_maxlcn; 18849930Ssklower size = (pkp -> pk_maxlcn + 1) * sizeof (struct pklcd *); 18949930Ssklower pkp -> pk_chan = 19049930Ssklower (struct pklcd **) malloc (size, M_IFADDR, M_WAITOK); 19149930Ssklower if (pkp -> pk_chan) { 192*57957Ssklower bzero ((caddr_t) pkp -> pk_chan, size); 19349930Ssklower /* 19449930Ssklower * Allocate a logical channel descriptor for lcn 0 19549930Ssklower */ 19649930Ssklower if (dev_lcp == 0 && 19749930Ssklower (dev_lcp = pk_attach ((struct socket *)0)) == 0) 19849930Ssklower return (ENOBUFS); 19949930Ssklower dev_lcp -> lcd_state = READY; 20049930Ssklower dev_lcp -> lcd_pkp = pkp; 20149930Ssklower pkp -> pk_chan[0] = dev_lcp; 20249930Ssklower } else { 20349930Ssklower if (dev_lcp) 20449930Ssklower pk_close (dev_lcp); 20549930Ssklower return (ENOBUFS); 20649930Ssklower } 20749930Ssklower } 20849930Ssklower return 0; 20949930Ssklower } 21049930Ssklower 21141591Ssklower /* 21241591Ssklower * This procedure is called by the link level whenever the link 21341591Ssklower * becomes operational, is reset, or when the link goes down. 21441591Ssklower */ 21557024Ssklower /*VARARGS*/ 21657024Ssklower caddr_t 21757024Ssklower pk_ctlinput (code, src, addr) 21857024Ssklower struct sockaddr *src; 21957024Ssklower caddr_t addr; 22041591Ssklower { 221*57957Ssklower register struct pkcb *pkp = (struct pkcb *) addr; 22241591Ssklower 22341591Ssklower switch (code) { 22441591Ssklower case PRC_LINKUP: 22541591Ssklower if (pkp -> pk_state == DTE_WAITING) 22641591Ssklower pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION); 22741591Ssklower break; 22841591Ssklower 22941591Ssklower case PRC_LINKDOWN: 23041591Ssklower pk_restart (pkp, -1); /* Clear all active circuits */ 23141591Ssklower pkp -> pk_state = DTE_WAITING; 23241591Ssklower break; 23341591Ssklower 23441591Ssklower case PRC_LINKRESET: 23541591Ssklower pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION); 23641591Ssklower break; 23757024Ssklower 23857024Ssklower case PRC_CONNECT_INDICATION: { 23957024Ssklower struct rtentry *llrt; 24041591Ssklower 24157024Ssklower if ((llrt = rtalloc1(src, 0)) == 0) 24257024Ssklower return 0; 243*57957Ssklower else llrt -> rt_refcnt--; 24457024Ssklower 245*57957Ssklower pkp = (((struct npaidbentry *) llrt -> rt_llinfo) -> np_rt) ? 246*57957Ssklower (struct pkcb *)(((struct npaidbentry *) llrt -> rt_llinfo) -> np_rt -> rt_llinfo) : (struct pkcb *) 0; 24757024Ssklower if (pkp == (struct pkcb *) 0) 24857024Ssklower return 0; 249*57957Ssklower pkp -> pk_llnext = addr; 25057024Ssklower 25157024Ssklower return ((caddr_t) pkp); 25241591Ssklower } 25357024Ssklower case PRC_DISCONNECT_INDICATION: 25457024Ssklower pk_restart (pkp, -1) ; /* Clear all active circuits */ 255*57957Ssklower pkp -> pk_state = DTE_WAITING; 256*57957Ssklower pkp -> pk_llnext = (caddr_t) 0; 25757024Ssklower } 25841591Ssklower return (0); 25941591Ssklower } 26045297Ssklower struct ifqueue pkintrq; 26145297Ssklower /* 26245297Ssklower * This routine is called if there are semi-smart devices that do HDLC 26345297Ssklower * in hardware and want to queue the packet and call level 3 directly 26445297Ssklower */ 26545297Ssklower pkintr () 26645297Ssklower { 26745297Ssklower register struct mbuf *m; 26845297Ssklower register struct ifaddr *ifa; 26945297Ssklower register struct ifnet *ifp; 27045297Ssklower register int s; 27141591Ssklower 27245297Ssklower for (;;) { 27345297Ssklower s = splimp (); 27445297Ssklower IF_DEQUEUE (&pkintrq, m); 27545297Ssklower splx (s); 27645297Ssklower if (m == 0) 27745297Ssklower break; 278*57957Ssklower if (m -> m_len < PKHEADERLN) { 27945297Ssklower printf ("pkintr: packet too short (len=%d)\n", 280*57957Ssklower m -> m_len); 28145297Ssklower m_freem (m); 28245297Ssklower continue; 28345297Ssklower } 284*57957Ssklower pk_input (m); 28545297Ssklower } 28645297Ssklower } 28745297Ssklower struct mbuf *pk_bad_packet; 28849593Ssklower struct mbuf_cache pk_input_cache = {0 }; 28941591Ssklower /* 29041591Ssklower * X.25 PACKET INPUT 29141591Ssklower * 29241591Ssklower * This procedure is called by a link level procedure whenever 29341591Ssklower * an information frame is received. It decodes the packet and 29441591Ssklower * demultiplexes based on the logical channel number. 29541591Ssklower * 29649930Ssklower * We change the original conventions of the UBC code here -- 29757955Ssklower * since there may be multiple pkcb's for a given interface 29857955Ssklower * of type 802.2 class 2, we retrieve which one it is from 29957955Ssklower * m_pkthdr.rcvif (which has been overwritten by lower layers); 30057955Ssklower * That field is then restored for the benefit of upper layers which 30157955Ssklower * may make use of it, such as CLNP. 302*57957Ssklower * 30341591Ssklower */ 30441591Ssklower 30557024Ssklower #define RESTART_DTE_ORIGINATED(xp) (((xp) -> packet_cause == X25_RESTART_DTE_ORIGINATED) || \ 30657024Ssklower ((xp) -> packet_cause >= X25_RESTART_DTE_ORIGINATED2)) 30757024Ssklower 30849930Ssklower pk_input (m) 30941591Ssklower register struct mbuf *m; 31041591Ssklower { 31141591Ssklower register struct x25_packet *xp; 31241591Ssklower register struct pklcd *lcp; 31341591Ssklower register struct socket *so = 0; 31441591Ssklower register struct pkcb *pkp; 31541591Ssklower int ptype, lcn, lcdstate = LISTEN; 31641591Ssklower 31749593Ssklower if (pk_input_cache.mbc_size || pk_input_cache.mbc_oldsize) 318*57957Ssklower mbuf_cache (&pk_input_cache, m); 319*57957Ssklower if ((m -> m_flags & M_PKTHDR) == 0) 320*57957Ssklower panic ("pkintr"); 32157024Ssklower 322*57957Ssklower if ((pkp = (struct pkcb *) m -> m_pkthdr.rcvif) == 0) 32349930Ssklower return; 32441591Ssklower xp = mtod (m, struct x25_packet *); 32541591Ssklower ptype = pk_decode (xp); 32645573Ssklower lcn = LCN(xp); 32741591Ssklower lcp = pkp -> pk_chan[lcn]; 32841591Ssklower 32941591Ssklower /* 33041591Ssklower * If the DTE is in Restart state, then it will ignore data, 33141591Ssklower * interrupt, call setup and clearing, flow control and reset 33241591Ssklower * packets. 33341591Ssklower */ 33441591Ssklower if (lcn < 0 || lcn > pkp -> pk_maxlcn) { 33541591Ssklower pk_message (lcn, pkp -> pk_xcp, "illegal lcn"); 33641591Ssklower m_freem (m); 33741591Ssklower return; 33841591Ssklower } 33941591Ssklower 34045895Ssklower pk_trace (pkp -> pk_xcp, m, "P-In"); 34141591Ssklower 34241591Ssklower if (pkp -> pk_state != DTE_READY && ptype != RESTART && ptype != RESTART_CONF) { 34341591Ssklower m_freem (m); 34441591Ssklower return; 34541591Ssklower } 34641591Ssklower if (lcp) { 34741591Ssklower so = lcp -> lcd_so; 34841591Ssklower lcdstate = lcp -> lcd_state; 34941591Ssklower } else { 35041591Ssklower if (ptype == CLEAR) { /* idle line probe (Datapac specific) */ 35141591Ssklower /* send response on lcd 0's output queue */ 35249930Ssklower lcp = pkp -> pk_chan[0]; 35341591Ssklower lcp -> lcd_template = pk_template (lcn, X25_CLEAR_CONFIRM); 35441591Ssklower pk_output (lcp); 35541591Ssklower m_freem (m); 35641591Ssklower return; 35741591Ssklower } 35841591Ssklower if (ptype != CALL) 35941591Ssklower ptype = INVALID_PACKET; 36041591Ssklower } 36141591Ssklower 36241591Ssklower if (lcn == 0 && ptype != RESTART && ptype != RESTART_CONF) { 36345297Ssklower pk_message (0, pkp -> pk_xcp, "illegal ptype (%d, %s) on lcn 0", 36445297Ssklower ptype, pk_name[ptype / MAXSTATES]); 36545297Ssklower if (pk_bad_packet) 36645297Ssklower m_freem (pk_bad_packet); 36745297Ssklower pk_bad_packet = m; 36841591Ssklower return; 36941591Ssklower } 37041591Ssklower 37157955Ssklower m -> m_pkthdr.rcvif = pkp -> pk_ia -> ia_ifp; 37257955Ssklower 37341591Ssklower switch (ptype + lcdstate) { 37441591Ssklower /* 37541591Ssklower * Incoming Call packet received. 37641591Ssklower */ 37741591Ssklower case CALL + LISTEN: 37849593Ssklower pk_incoming_call (pkp, m); 37941591Ssklower break; 38041591Ssklower 38141591Ssklower /* 38241591Ssklower * Call collision: Just throw this "incoming call" away since 38341591Ssklower * the DCE will ignore it anyway. 38441591Ssklower */ 38541591Ssklower case CALL + SENT_CALL: 386*57957Ssklower pk_message ((int) lcn, pkp -> pk_xcp, 38741591Ssklower "incoming call collision"); 38841591Ssklower break; 38941591Ssklower 39041591Ssklower /* 39141591Ssklower * Call confirmation packet received. This usually means our 39241591Ssklower * previous connect request is now complete. 39341591Ssklower */ 39441591Ssklower case CALL_ACCEPTED + SENT_CALL: 39549252Ssklower MCHTYPE(m, MT_CONTROL); 39649593Ssklower pk_call_accepted (lcp, m); 39741591Ssklower break; 39841591Ssklower 39941591Ssklower /* 40041591Ssklower * This condition can only happen if the previous state was 40141591Ssklower * SENT_CALL. Just ignore the packet, eventually a clear 40241591Ssklower * confirmation should arrive. 40341591Ssklower */ 40441591Ssklower case CALL_ACCEPTED + SENT_CLEAR: 40541591Ssklower break; 40641591Ssklower 40741591Ssklower /* 40841591Ssklower * Clear packet received. This requires a complete tear down 40941591Ssklower * of the virtual circuit. Free buffers and control blocks. 41041591Ssklower * and send a clear confirmation. 41141591Ssklower */ 41241591Ssklower case CLEAR + READY: 41341591Ssklower case CLEAR + RECEIVED_CALL: 41441591Ssklower case CLEAR + SENT_CALL: 41541591Ssklower case CLEAR + DATA_TRANSFER: 41641591Ssklower lcp -> lcd_state = RECEIVED_CLEAR; 41741591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CLEAR_CONFIRM); 41841591Ssklower pk_output (lcp); 41941591Ssklower pk_clearcause (pkp, xp); 42049252Ssklower if (lcp -> lcd_upper) { 42149252Ssklower MCHTYPE(m, MT_CONTROL); 42249252Ssklower lcp -> lcd_upper (lcp, m); 42349252Ssklower } 42441591Ssklower pk_close (lcp); 42549252Ssklower lcp = 0; 42641591Ssklower break; 42741591Ssklower 42841591Ssklower /* 42941591Ssklower * Clear collision: Treat this clear packet as a confirmation. 43041591Ssklower */ 43141591Ssklower case CLEAR + SENT_CLEAR: 43241591Ssklower pk_close (lcp); 43341591Ssklower break; 43441591Ssklower 43541591Ssklower /* 43641591Ssklower * Clear confirmation received. This usually means the virtual 43741591Ssklower * circuit is now completely removed. 43841591Ssklower */ 43941591Ssklower case CLEAR_CONF + SENT_CLEAR: 44041591Ssklower pk_close (lcp); 44141591Ssklower break; 44241591Ssklower 44341591Ssklower /* 44441591Ssklower * A clear confirmation on an unassigned logical channel - just 44541591Ssklower * ignore it. Note: All other packets on an unassigned channel 44641591Ssklower * results in a clear. 44741591Ssklower */ 44841591Ssklower case CLEAR_CONF + READY: 44949930Ssklower case CLEAR_CONF + LISTEN: 45041591Ssklower break; 45141591Ssklower 45241591Ssklower /* 45341591Ssklower * Data packet received. Pass on to next level. Move the Q and M 45441591Ssklower * bits into the data portion for the next level. 45541591Ssklower */ 45641591Ssklower case DATA + DATA_TRANSFER: 45741591Ssklower if (lcp -> lcd_reset_condition) { 45841591Ssklower ptype = DELETE_PACKET; 45941591Ssklower break; 46041591Ssklower } 46141591Ssklower 46241591Ssklower /* 46341591Ssklower * Process the P(S) flow control information in this Data packet. 46441591Ssklower * Check that the packets arrive in the correct sequence and that 46541591Ssklower * they are within the "lcd_input_window". Input window rotation is 46641591Ssklower * initiated by the receive interface. 46741591Ssklower */ 46841591Ssklower 46941591Ssklower if (PS(xp) != ((lcp -> lcd_rsn + 1) % MODULUS) || 470*57957Ssklower PS(xp) == ((lcp -> lcd_input_window + lcp -> lcd_windowsize) % MODULUS)) { 47141591Ssklower m_freem (m); 47245895Ssklower pk_procerror (RESET, lcp, "p(s) flow control error", 1); 47341591Ssklower break; 47441591Ssklower } 47541591Ssklower lcp -> lcd_rsn = PS(xp); 47641591Ssklower 47741591Ssklower if (pk_ack (lcp, PR(xp)) != PACKET_OK) { 47841591Ssklower m_freem (m); 47941591Ssklower break; 48041591Ssklower } 48145895Ssklower m -> m_data += PKHEADERLN; 48245895Ssklower m -> m_len -= PKHEADERLN; 48345895Ssklower m -> m_pkthdr.len -= PKHEADERLN; 48445895Ssklower 48549930Ssklower lcp -> lcd_rxcnt++; 48645895Ssklower if (lcp -> lcd_flags & X25_MBS_HOLD) { 48745895Ssklower register struct mbuf *n = lcp -> lcd_cps; 48845895Ssklower int mbit = MBIT(xp); 48945895Ssklower octet q_and_d_bits; 49045895Ssklower 49145895Ssklower if (n) { 49245895Ssklower n -> m_pkthdr.len += m -> m_pkthdr.len; 49345895Ssklower while (n -> m_next) 49445895Ssklower n = n -> m_next; 49545895Ssklower n -> m_next = m; 49645895Ssklower m = lcp -> lcd_cps; 49745895Ssklower 49845895Ssklower if (lcp -> lcd_cpsmax && 49945895Ssklower n -> m_pkthdr.len > lcp -> lcd_cpsmax) { 50045895Ssklower pk_procerror (RESET, lcp, 50145895Ssklower "C.P.S. overflow", 128); 50245895Ssklower return; 50345895Ssklower } 504*57957Ssklower q_and_d_bits = 0xc0 & *(octet *) xp; 50545895Ssklower xp = (struct x25_packet *) 506*57957Ssklower (mtod (m, octet *) - PKHEADERLN); 507*57957Ssklower *(octet *) xp |= q_and_d_bits; 50845895Ssklower } 50945895Ssklower if (mbit) { 51045895Ssklower lcp -> lcd_cps = m; 511*57957Ssklower pk_flowcontrol (lcp, 0, 1); 51245895Ssklower return; 51345895Ssklower } 51445895Ssklower lcp -> lcd_cps = 0; 51545895Ssklower } 51645297Ssklower if (so == 0) 51745297Ssklower break; 51841591Ssklower if (lcp -> lcd_flags & X25_MQBIT) { 51957024Ssklower octet t = (X25GBITS(xp -> bits, q_bit)) ? t = 0x80 : 0; 52041591Ssklower 52145573Ssklower if (MBIT(xp)) 52245573Ssklower t |= 0x40; 52343361Ssklower m -> m_data -= 1; 52441591Ssklower m -> m_len += 1; 52545895Ssklower m -> m_pkthdr.len += 1; 526*57957Ssklower *mtod (m, octet *) = t; 52741591Ssklower } 52841591Ssklower 52941591Ssklower /* 53041591Ssklower * Discard Q-BIT packets if the application 53141591Ssklower * doesn't want to be informed of M and Q bit status 53241591Ssklower */ 53357024Ssklower if (X25GBITS(xp -> bits, q_bit) 53457024Ssklower && (lcp -> lcd_flags & X25_MQBIT) == 0) { 53541591Ssklower m_freem (m); 53641591Ssklower /* 53741591Ssklower * NB. This is dangerous: sending a RR here can 53841591Ssklower * cause sequence number errors if a previous data 53941591Ssklower * packet has not yet been passed up to the application 54041591Ssklower * (RR's are normally generated via PRU_RCVD). 54141591Ssklower */ 542*57957Ssklower pk_flowcontrol (lcp, 0, 1); 54341591Ssklower } else { 54441591Ssklower sbappendrecord (&so -> so_rcv, m); 54541591Ssklower sorwakeup (so); 54641591Ssklower } 54741591Ssklower break; 54841591Ssklower 54941591Ssklower /* 55041591Ssklower * Interrupt packet received. 55141591Ssklower */ 55241591Ssklower case INTERRUPT + DATA_TRANSFER: 55341591Ssklower if (lcp -> lcd_reset_condition) 55441591Ssklower break; 55541591Ssklower lcp -> lcd_intrdata = xp -> packet_data; 55641591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM); 55741591Ssklower pk_output (lcp); 55845895Ssklower m -> m_data += PKHEADERLN; 55945895Ssklower m -> m_len -= PKHEADERLN; 56045895Ssklower m -> m_pkthdr.len -= PKHEADERLN; 56145297Ssklower MCHTYPE(m, MT_OOBDATA); 56245895Ssklower if (so) { 56345895Ssklower if (so -> so_options & SO_OOBINLINE) 56445895Ssklower sbinsertoob (&so -> so_rcv, m); 56545895Ssklower else 56645895Ssklower m_freem (m); 56745297Ssklower sohasoutofband (so); 56845895Ssklower } 56941591Ssklower break; 57041591Ssklower 57141591Ssklower /* 57241591Ssklower * Interrupt confirmation packet received. 57341591Ssklower */ 57441591Ssklower case INTERRUPT_CONF + DATA_TRANSFER: 57541591Ssklower if (lcp -> lcd_reset_condition) 57641591Ssklower break; 57741591Ssklower if (lcp -> lcd_intrconf_pending == TRUE) 57841591Ssklower lcp -> lcd_intrconf_pending = FALSE; 57941591Ssklower else 58045895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 43); 58141591Ssklower break; 58241591Ssklower 58341591Ssklower /* 58441591Ssklower * Receiver ready received. Rotate the output window and output 58541591Ssklower * any data packets waiting transmission. 58641591Ssklower */ 58741591Ssklower case RR + DATA_TRANSFER: 58845297Ssklower if (lcp -> lcd_reset_condition || 58945297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 59045297Ssklower ptype = DELETE_PACKET; 59141591Ssklower break; 59245297Ssklower } 59341591Ssklower if (lcp -> lcd_rnr_condition == TRUE) 59441591Ssklower lcp -> lcd_rnr_condition = FALSE; 59541591Ssklower pk_output (lcp); 59641591Ssklower break; 59741591Ssklower 59841591Ssklower /* 59941591Ssklower * Receiver Not Ready received. Packets up to the P(R) can be 60041591Ssklower * be sent. Condition is cleared with a RR. 60141591Ssklower */ 60241591Ssklower case RNR + DATA_TRANSFER: 60345297Ssklower if (lcp -> lcd_reset_condition || 60445297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 60545297Ssklower ptype = DELETE_PACKET; 60641591Ssklower break; 60745297Ssklower } 60841591Ssklower lcp -> lcd_rnr_condition = TRUE; 60941591Ssklower break; 61041591Ssklower 61141591Ssklower /* 61241591Ssklower * Reset packet received. Set state to FLOW_OPEN. The Input and 61341591Ssklower * Output window edges ar set to zero. Both the send and receive 61441591Ssklower * numbers are reset. A confirmation is returned. 61541591Ssklower */ 61641591Ssklower case RESET + DATA_TRANSFER: 61741591Ssklower if (lcp -> lcd_reset_condition) 61841591Ssklower /* Reset collision. Just ignore packet. */ 61941591Ssklower break; 62041591Ssklower 62141591Ssklower pk_resetcause (pkp, xp); 62241591Ssklower lcp -> lcd_window_condition = lcp -> lcd_rnr_condition = 62341591Ssklower lcp -> lcd_intrconf_pending = FALSE; 62441591Ssklower lcp -> lcd_output_window = lcp -> lcd_input_window = 62541591Ssklower lcp -> lcd_last_transmitted_pr = 0; 62641591Ssklower lcp -> lcd_ssn = 0; 62741591Ssklower lcp -> lcd_rsn = MODULUS - 1; 62841591Ssklower 62941591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM); 63041591Ssklower pk_output (lcp); 63145297Ssklower 632*57957Ssklower pk_flush (lcp); 63345297Ssklower if (so == 0) 63445297Ssklower break; 63545297Ssklower wakeup ((caddr_t) & so -> so_timeo); 63645297Ssklower sorwakeup (so); 63745297Ssklower sowwakeup (so); 63841591Ssklower break; 63941591Ssklower 64041591Ssklower /* 64141591Ssklower * Reset confirmation received. 64241591Ssklower */ 64341591Ssklower case RESET_CONF + DATA_TRANSFER: 64441591Ssklower if (lcp -> lcd_reset_condition) { 64541591Ssklower lcp -> lcd_reset_condition = FALSE; 64641591Ssklower pk_output (lcp); 64741591Ssklower } 64841591Ssklower else 64945895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 32); 65041591Ssklower break; 65141591Ssklower 65241591Ssklower case DATA + SENT_CLEAR: 65341591Ssklower ptype = DELETE_PACKET; 65441591Ssklower case RR + SENT_CLEAR: 65541591Ssklower case RNR + SENT_CLEAR: 65641591Ssklower case INTERRUPT + SENT_CLEAR: 65741591Ssklower case INTERRUPT_CONF + SENT_CLEAR: 65841591Ssklower case RESET + SENT_CLEAR: 65941591Ssklower case RESET_CONF + SENT_CLEAR: 66045297Ssklower /* Just ignore p if we have sent a CLEAR already. 66141591Ssklower */ 66241591Ssklower break; 66341591Ssklower 66441591Ssklower /* 66541591Ssklower * Restart sets all the permanent virtual circuits to the "Data 66641591Ssklower * Transfer" stae and all the switched virtual circuits to the 66741591Ssklower * "Ready" state. 66841591Ssklower */ 66941591Ssklower case RESTART + READY: 67041591Ssklower switch (pkp -> pk_state) { 67141591Ssklower case DTE_SENT_RESTART: 67257024Ssklower /* 67357024Ssklower * Restart collision. 67457024Ssklower * If case the restart cause is "DTE originated" we 67557024Ssklower * have a DTE-DTE situation and are trying to resolve 67657024Ssklower * who is going to play DTE/DCE [ISO 8208:4.2-4.5] 67757024Ssklower */ 67857024Ssklower if (RESTART_DTE_ORIGINATED(xp)) { 67957024Ssklower pk_restart (pkp, X25_RESTART_DTE_ORIGINATED); 68057024Ssklower pk_message (0, pkp -> pk_xcp, 68157024Ssklower "RESTART collision"); 68257024Ssklower if ((pkp -> pk_restartcolls++) > MAXRESTARTCOLLISIONS) { 68357024Ssklower pk_message (0, pkp -> pk_xcp, 68457024Ssklower "excessive RESTART collisions"); 68557024Ssklower pkp -> pk_restartcolls = 0; 68657024Ssklower } 68757024Ssklower break; 68857024Ssklower } 68941591Ssklower pkp -> pk_state = DTE_READY; 69057024Ssklower pkp -> pk_dxerole |= DTE_PLAYDTE; 69157024Ssklower pkp -> pk_dxerole &= ~DTE_PLAYDCE; 69241591Ssklower pk_message (0, pkp -> pk_xcp, 69341591Ssklower "Packet level operational"); 69457024Ssklower pk_message (0, pkp -> pk_xcp, 69557024Ssklower "Assuming DTE role"); 69657024Ssklower if (pkp -> pk_dxerole & DTE_CONNECTPENDING) 697*57957Ssklower pk_callcomplete (pkp); 69841591Ssklower break; 69941591Ssklower 70041591Ssklower default: 70141591Ssklower pk_restart (pkp, -1); 70241591Ssklower pk_restartcause (pkp, xp); 70341591Ssklower pkp -> pk_chan[0] -> lcd_template = pk_template (0, 70441591Ssklower X25_RESTART_CONFIRM); 70541591Ssklower pk_output (pkp -> pk_chan[0]); 70657024Ssklower pkp -> pk_state = DTE_READY; 70757024Ssklower pkp -> pk_dxerole |= RESTART_DTE_ORIGINATED(xp) ? DTE_PLAYDCE : 70857024Ssklower DTE_PLAYDTE; 70957024Ssklower if (pkp -> pk_dxerole & DTE_PLAYDTE) { 71057024Ssklower pkp -> pk_dxerole &= ~DTE_PLAYDCE; 71157024Ssklower pk_message (0, pkp -> pk_xcp, 71257024Ssklower "Assuming DTE role"); 71357024Ssklower } else { 71457024Ssklower pkp -> pk_dxerole &= ~DTE_PLAYDTE; 71557024Ssklower pk_message (0, pkp -> pk_xcp, 71657024Ssklower "Assuming DCE role"); 71757024Ssklower } 71857024Ssklower if (pkp -> pk_dxerole & DTE_CONNECTPENDING) 719*57957Ssklower pk_callcomplete (pkp); 72041591Ssklower } 72141591Ssklower break; 72241591Ssklower 72341591Ssklower /* 72441591Ssklower * Restart confirmation received. All logical channels are set 72541591Ssklower * to READY. 72641591Ssklower */ 72741591Ssklower case RESTART_CONF + READY: 72841591Ssklower switch (pkp -> pk_state) { 72941591Ssklower case DTE_SENT_RESTART: 73041591Ssklower pkp -> pk_state = DTE_READY; 73157024Ssklower pkp -> pk_dxerole |= DTE_PLAYDTE; 73257024Ssklower pkp -> pk_dxerole &= ~DTE_PLAYDCE; 73341591Ssklower pk_message (0, pkp -> pk_xcp, 73457024Ssklower "Packet level operational"); 735*57957Ssklower pk_message (0, pkp -> pk_xcp, 73657024Ssklower "Assuming DTE role"); 73757024Ssklower if (pkp -> pk_dxerole & DTE_CONNECTPENDING) 738*57957Ssklower pk_callcomplete (pkp); 73941591Ssklower break; 74041591Ssklower 74141591Ssklower default: 74241591Ssklower /* Restart local procedure error. */ 74341591Ssklower pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR); 74441591Ssklower pkp -> pk_state = DTE_SENT_RESTART; 74557024Ssklower pkp -> pk_dxerole &= ~(DTE_PLAYDTE | DTE_PLAYDCE); 74641591Ssklower } 74741591Ssklower break; 74841591Ssklower 74941591Ssklower default: 75041591Ssklower if (lcp) { 75145895Ssklower pk_procerror (CLEAR, lcp, "unknown packet error", 33); 75241591Ssklower pk_message (lcn, pkp -> pk_xcp, 75341591Ssklower "\"%s\" unexpected in \"%s\" state", 75441591Ssklower pk_name[ptype/MAXSTATES], pk_state[lcdstate]); 75545895Ssklower } else 75645573Ssklower pk_message (lcn, pkp -> pk_xcp, 75741591Ssklower "packet arrived on unassigned lcn"); 75841591Ssklower break; 75941591Ssklower } 76049252Ssklower if (so == 0 && lcp && lcp -> lcd_upper && lcdstate == DATA_TRANSFER) { 76145895Ssklower if (ptype != DATA && ptype != INTERRUPT) 76245895Ssklower MCHTYPE(m, MT_CONTROL); 76345297Ssklower lcp -> lcd_upper (lcp, m); 76445895Ssklower } else if (ptype != DATA && ptype != INTERRUPT) 76541591Ssklower m_freem (m); 76641591Ssklower } 76741591Ssklower 76849930Ssklower static 769*57957Ssklower prune_dnic (from, to, dnicname, xcp) 77049930Ssklower char *from, *to, *dnicname; 77149930Ssklower register struct x25config *xcp; 77249930Ssklower { 77349930Ssklower register char *cp1 = from, *cp2 = from; 774*57957Ssklower if (xcp -> xc_prepnd0 && *cp1 == '0') { 77549930Ssklower from = ++cp1; 77649930Ssklower goto copyrest; 77749930Ssklower } 778*57957Ssklower if (xcp -> xc_nodnic) { 77949930Ssklower for (cp1 = dnicname; *cp2 = *cp1++;) 78049930Ssklower cp2++; 78149930Ssklower cp1 = from; 78249930Ssklower } 78349930Ssklower copyrest: 78449930Ssklower for (cp1 = dnicname; *cp2 = *cp1++;) 78549930Ssklower cp2++; 78649930Ssklower } 78749930Ssklower /* static */ 78849930Ssklower pk_simple_bsd (from, to, lower, len) 78949930Ssklower register octet *from, *to; 79049930Ssklower register len, lower; 79149930Ssklower { 79249930Ssklower register int c; 79349930Ssklower while (--len >= 0) { 79449930Ssklower c = *from; 79549930Ssklower if (lower & 0x01) 79649930Ssklower *from++; 79749930Ssklower else 79849930Ssklower c >>= 4; 79949930Ssklower c &= 0x0f; c |= 0x30; *to++ = c; lower++; 80049930Ssklower } 80149930Ssklower *to = 0; 80249930Ssklower } 80341591Ssklower 80449930Ssklower /*static octet * */ 80549930Ssklower pk_from_bcd (a, iscalling, sa, xcp) 80649930Ssklower register struct x25_calladdr *a; 80749930Ssklower register struct sockaddr_x25 *sa; 80849930Ssklower register struct x25config *xcp; 80949930Ssklower { 81049930Ssklower octet buf[MAXADDRLN+1]; 81149930Ssklower octet *cp; 81249930Ssklower unsigned count; 81349930Ssklower 814*57957Ssklower bzero ((caddr_t) sa, sizeof (*sa)); 81549930Ssklower sa -> x25_len = sizeof (*sa); 81649930Ssklower sa -> x25_family = AF_CCITT; 81749930Ssklower if (iscalling) { 81857024Ssklower cp = a -> address_field + (X25GBITS(a -> addrlens, called_addrlen) / 2); 81957024Ssklower count = X25GBITS(a -> addrlens, calling_addrlen); 82057024Ssklower pk_simple_bsd (cp, buf, X25GBITS(a -> addrlens, called_addrlen), count); 82149930Ssklower } else { 82257024Ssklower count = X25GBITS(a -> addrlens, called_addrlen); 82349930Ssklower pk_simple_bsd (a -> address_field, buf, 0, count); 82449930Ssklower } 825*57957Ssklower if (xcp -> xc_addr.x25_net && (xcp -> xc_nodnic || xcp -> xc_prepnd0)) { 826*57957Ssklower octet dnicname[sizeof (long) * NBBY/3 + 2]; 82749930Ssklower 82857024Ssklower sprintf ((char *) dnicname, "%d", xcp -> xc_addr.x25_net); 829*57957Ssklower prune_dnic ((char *) buf, sa -> x25_addr, dnicname, xcp); 83049930Ssklower } else 831*57957Ssklower bcopy ((caddr_t) buf, (caddr_t) sa -> x25_addr, count + 1); 83249930Ssklower } 83349930Ssklower 83449930Ssklower static 835*57957Ssklower save_extra (m0, fp, so) 83649930Ssklower struct mbuf *m0; 83749930Ssklower octet *fp; 83849930Ssklower struct socket *so; 83949930Ssklower { 84049930Ssklower register struct mbuf *m; 84149930Ssklower struct cmsghdr cmsghdr; 84252449Ssklower if (m = m_copy (m, 0, (int)M_COPYALL)) { 84349930Ssklower int off = fp - mtod (m0, octet *); 844*57957Ssklower int len = m -> m_pkthdr.len - off + sizeof (cmsghdr); 84549930Ssklower cmsghdr.cmsg_len = len; 84649930Ssklower cmsghdr.cmsg_level = AF_CCITT; 84749930Ssklower cmsghdr.cmsg_type = PK_FACILITIES; 84849930Ssklower m_adj (m, off); 849*57957Ssklower M_PREPEND (m, sizeof (cmsghdr), M_DONTWAIT); 85049930Ssklower if (m == 0) 85149930Ssklower return; 85249930Ssklower bcopy ((caddr_t)&cmsghdr, mtod (m, caddr_t), sizeof (cmsghdr)); 85349930Ssklower MCHTYPE(m, MT_CONTROL); 854*57957Ssklower sbappendrecord (&so -> so_rcv, m); 85549930Ssklower } 85649930Ssklower } 85749930Ssklower 85841591Ssklower /* 85941591Ssklower * This routine handles incoming call packets. It matches the protocol 86041591Ssklower * field on the Call User Data field (usually the first four bytes) with 86141591Ssklower * sockets awaiting connections. 86241591Ssklower */ 86341591Ssklower 86449593Ssklower pk_incoming_call (pkp, m0) 86545895Ssklower struct mbuf *m0; 86641591Ssklower struct pkcb *pkp; 86741591Ssklower { 86842277Ssklower register struct pklcd *lcp = 0, *l; 86941591Ssklower register struct sockaddr_x25 *sa; 87041591Ssklower register struct x25_calladdr *a; 87142277Ssklower register struct socket *so = 0; 872*57957Ssklower struct x25_packet *xp = mtod (m0, struct x25_packet *); 87349930Ssklower struct mbuf *m; 87449930Ssklower struct x25config *xcp = pkp -> pk_xcp; 875*57957Ssklower int len = m0 -> m_pkthdr.len; 87649930Ssklower unsigned udlen; 87749930Ssklower char *errstr = "server unavailable"; 87845895Ssklower octet *u, *facp; 87945573Ssklower int lcn = LCN(xp); 88041591Ssklower 88149930Ssklower /* First, copy the data from the incoming call packet to a X25 address 88249930Ssklower descriptor. It is to be regretted that you have 88349930Ssklower to parse the facilities into a sockaddr to determine 88449930Ssklower if reverse charging is being requested */ 88549930Ssklower if ((m = m_get (M_DONTWAIT, MT_SONAME)) == 0) 88641591Ssklower return; 88741591Ssklower sa = mtod (m, struct sockaddr_x25 *); 88849930Ssklower a = (struct x25_calladdr *) &xp -> packet_data; 88949930Ssklower facp = u = (octet *) (a -> address_field + 89057024Ssklower ((X25GBITS(a -> addrlens, called_addrlen) + X25GBITS(a -> addrlens, calling_addrlen) + 1) / 2)); 89149930Ssklower u += *u + 1; 892*57957Ssklower udlen = min (16, ((octet *) xp) + len - u); 89349930Ssklower if (udlen < 0) 89449930Ssklower udlen = 0; 89549930Ssklower pk_from_bcd (a, 1, sa, pkp -> pk_xcp); /* get calling address */ 89650426Ssklower pk_parse_facilities (facp, sa); 897*57957Ssklower bcopy ((caddr_t) u, sa -> x25_udata, udlen); 89849930Ssklower sa -> x25_udlen = udlen; 89941591Ssklower 90041591Ssklower /* 90150426Ssklower * Now, loop through the listen sockets looking for a match on the 90250426Ssklower * PID. That is the first few octets of the user data field. 90350426Ssklower * This is the closest thing to a port number for X.25 packets. 90450426Ssklower * It does provide a way of multiplexing services at the user level. 90541591Ssklower */ 90641591Ssklower 90741591Ssklower for (l = pk_listenhead; l; l = l -> lcd_listen) { 90841591Ssklower struct sockaddr_x25 *sxp = l -> lcd_ceaddr; 90941591Ssklower 910*57957Ssklower if (bcmp (sxp -> x25_udata, u, sxp -> x25_udlen)) 91141591Ssklower continue; 91245165Ssklower if (sxp -> x25_net && 91349930Ssklower sxp -> x25_net != xcp -> xc_addr.x25_net) 91441591Ssklower continue; 91541591Ssklower /* 91649930Ssklower * don't accept incoming calls with the D-Bit on 91749930Ssklower * unless the server agrees 91849930Ssklower */ 91957024Ssklower if (X25GBITS(xp -> bits, d_bit) && !(sxp -> x25_opts.op_flags & X25_DBIT)) { 92049930Ssklower errstr = "incoming D-Bit mismatch"; 92149930Ssklower break; 92249930Ssklower } 92349930Ssklower /* 92441591Ssklower * don't accept incoming collect calls unless 92541591Ssklower * the server sets the reverse charging option. 92641591Ssklower */ 92741591Ssklower if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 && 92841591Ssklower sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) { 92941591Ssklower errstr = "incoming collect call refused"; 93041591Ssklower break; 93141591Ssklower } 93242277Ssklower if (l -> lcd_so) { 93345165Ssklower if (so = sonewconn (l -> lcd_so, SS_ISCONNECTED)) 93442277Ssklower lcp = (struct pklcd *) so -> so_pcb; 93542277Ssklower } else 936*57957Ssklower lcp = pk_attach ((struct socket *) 0); 93742277Ssklower if (lcp == 0) { 93841591Ssklower /* 93941591Ssklower * Insufficient space or too many unaccepted 94041591Ssklower * connections. Just throw the call away. 94141591Ssklower */ 94241591Ssklower errstr = "server malfunction"; 94341591Ssklower break; 94441591Ssklower } 94543361Ssklower lcp -> lcd_upper = l -> lcd_upper; 94643361Ssklower lcp -> lcd_upnext = l -> lcd_upnext; 94741591Ssklower lcp -> lcd_lcn = lcn; 94841591Ssklower lcp -> lcd_state = RECEIVED_CALL; 94950020Ssklower sa -> x25_opts.op_flags |= (sxp -> x25_opts.op_flags & 95050020Ssklower ~X25_REVERSE_CHARGE) | l -> lcd_flags; 95141591Ssklower pk_assoc (pkp, lcp, sa); 95249930Ssklower lcp -> lcd_faddr = *sa; 95349930Ssklower lcp -> lcd_laddr.x25_udlen = sxp -> x25_udlen; 954*57957Ssklower lcp -> lcd_craddr = &lcp -> lcd_faddr; 95541591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED); 95645573Ssklower if (lcp -> lcd_flags & X25_DBIT) { 95757024Ssklower if (X25GBITS(xp -> bits, d_bit)) 958*57957Ssklower X25SBITS(mtod (lcp -> lcd_template, 95957024Ssklower struct x25_packet *) -> bits, d_bit, 1); 96045573Ssklower else 96145573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 96245573Ssklower } 96343361Ssklower if (so) { 96443361Ssklower pk_output (lcp); 96542277Ssklower soisconnected (so); 96645895Ssklower if (so -> so_options & SO_OOBINLINE) 967*57957Ssklower save_extra (m0, facp, so); 96845895Ssklower } else if (lcp -> lcd_upper) { 96949930Ssklower (*lcp -> lcd_upper) (lcp, m0); 97045895Ssklower } 97149930Ssklower (void) m_free (m); 97241591Ssklower return; 97341591Ssklower } 97441591Ssklower 97541591Ssklower /* 97641591Ssklower * If the call fails for whatever reason, we still need to build a 97741591Ssklower * skeleton LCD in order to be able to properly receive the CLEAR 97841591Ssklower * CONFIRMATION. 97941591Ssklower */ 98041591Ssklower #ifdef WATERLOO /* be explicit */ 981*57957Ssklower if (l == 0 && bcmp (sa -> x25_udata, "ean", 3) == 0) 98241591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s", 983*57957Ssklower sa -> x25_addr, sa -> x25_udata[3] & 0xff, errstr); 984*57957Ssklower else if (l == 0 && bcmp (sa -> x25_udata, "\1\0\0\0", 4) == 0) 98541591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s", 986*57957Ssklower sa -> x25_addr, errstr); 98741591Ssklower else 98841591Ssklower #endif 98941591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s", 99041591Ssklower sa -> x25_addr, sa -> x25_udata[0] & 0xff, 99141591Ssklower sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff, 99241591Ssklower sa -> x25_udata[3] & 0xff, errstr); 993*57957Ssklower if ((lcp = pk_attach ((struct socket *)0)) == 0) { 99445297Ssklower (void) m_free (m); 99541591Ssklower return; 99641591Ssklower } 99741591Ssklower lcp -> lcd_lcn = lcn; 99841591Ssklower lcp -> lcd_state = RECEIVED_CALL; 99941591Ssklower pk_assoc (pkp, lcp, sa); 100045297Ssklower (void) m_free (m); 100145895Ssklower pk_clear (lcp, 0, 1); 100241591Ssklower } 100341591Ssklower 100449593Ssklower pk_call_accepted (lcp, m) 100541591Ssklower struct pklcd *lcp; 100649252Ssklower struct mbuf *m; 100741591Ssklower { 100841591Ssklower register struct x25_calladdr *ap; 100941591Ssklower register octet *fcp; 101049252Ssklower struct x25_packet *xp = mtod (m, struct x25_packet *); 101149252Ssklower int len = m -> m_len; 101241591Ssklower 101341591Ssklower lcp -> lcd_state = DATA_TRANSFER; 101445297Ssklower if (lcp -> lcd_so) 101545297Ssklower soisconnected (lcp -> lcd_so); 101657024Ssklower if ((lcp -> lcd_flags & X25_DBIT) && (X25GBITS(xp -> bits, d_bit) == 0)) 101745573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 101841591Ssklower if (len > 3) { 101941591Ssklower ap = (struct x25_calladdr *) &xp -> packet_data; 102057024Ssklower fcp = (octet *) ap -> address_field + (X25GBITS(ap -> addrlens, calling_addrlen) + 102157024Ssklower X25GBITS(ap -> addrlens, called_addrlen) + 1) / 2; 1022*57957Ssklower if (fcp + *fcp <= ((octet *) xp) + len) 102349593Ssklower pk_parse_facilities (fcp, lcp -> lcd_ceaddr); 102441591Ssklower } 102541591Ssklower pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr); 102649252Ssklower if (lcp -> lcd_so == 0 && lcp -> lcd_upper) 1027*57957Ssklower lcp -> lcd_upper (lcp, m); 102841591Ssklower } 102941591Ssklower 103049593Ssklower pk_parse_facilities (fcp, sa) 103141591Ssklower register octet *fcp; 103241591Ssklower register struct sockaddr_x25 *sa; 103341591Ssklower { 103441591Ssklower register octet *maxfcp; 103541591Ssklower 103641591Ssklower maxfcp = fcp + *fcp; 103741591Ssklower fcp++; 103841591Ssklower while (fcp < maxfcp) { 103941591Ssklower /* 104041591Ssklower * Ignore national DCE or DTE facilities 104141591Ssklower */ 104241591Ssklower if (*fcp == 0 || *fcp == 0xff) 104341591Ssklower break; 104441591Ssklower switch (*fcp) { 104541591Ssklower case FACILITIES_WINDOWSIZE: 104641591Ssklower sa -> x25_opts.op_wsize = fcp[1]; 104741591Ssklower fcp += 3; 104841591Ssklower break; 104941591Ssklower 105041591Ssklower case FACILITIES_PACKETSIZE: 105141591Ssklower sa -> x25_opts.op_psize = fcp[1]; 105241591Ssklower fcp += 3; 105341591Ssklower break; 105441591Ssklower 105541591Ssklower case FACILITIES_THROUGHPUT: 105641591Ssklower sa -> x25_opts.op_speed = fcp[1]; 105741591Ssklower fcp += 2; 105841591Ssklower break; 105941591Ssklower 106041591Ssklower case FACILITIES_REVERSE_CHARGE: 106141591Ssklower if (fcp[1] & 01) 106241591Ssklower sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE; 106341591Ssklower /* 106441591Ssklower * Datapac specific: for a X.25(1976) DTE, bit 2 106541591Ssklower * indicates a "hi priority" (eg. international) call. 106641591Ssklower */ 106741591Ssklower if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0) 106841591Ssklower sa -> x25_opts.op_psize = X25_PS128; 106941591Ssklower fcp += 2; 107041591Ssklower break; 107141591Ssklower 107241591Ssklower default: 107341591Ssklower /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/ 107441591Ssklower switch ((*fcp & 0xc0) >> 6) { 107541591Ssklower case 0: /* class A */ 107641591Ssklower fcp += 2; 107741591Ssklower break; 107841591Ssklower 107941591Ssklower case 1: 108041591Ssklower fcp += 3; 108141591Ssklower break; 108241591Ssklower 108341591Ssklower case 2: 108441591Ssklower fcp += 4; 108541591Ssklower break; 108641591Ssklower 108741591Ssklower case 3: 108841591Ssklower fcp++; 108941591Ssklower fcp += *fcp; 109041591Ssklower } 109141591Ssklower } 109241591Ssklower } 109341591Ssklower } 1094