141709Ssklower /* 241709Ssklower * Copyright (c) University of British Columbia, 1984 3*57024Ssklower * Copyright (C) Computer Science Department IV, 4*57024Ssklower * University of Erlangen-Nuremberg, Germany, 1992 5*57024Ssklower * Copyright (c) 1991, 1992 The Regents of the University of California. 641709Ssklower * All rights reserved. 741709Ssklower * 8*57024Ssklower * This code is derived from software contributed to Berkeley by the 9*57024Ssklower * Laboratory for Computation Vision and the Computer Science Department 10*57024Ssklower * of the the University of British Columbia and the Computer Science 11*57024Ssklower * Department (IV) of the University of Erlangen-Nuremberg, Germany. 1241709Ssklower * 1341709Ssklower * %sccs.include.redist.c% 1441709Ssklower * 15*57024Ssklower * @(#)pk_input.c 7.17 (Berkeley) 12/08/92 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> 2741591Ssklower 28*57024Ssklower #include <netccitt/dll.h> 2956530Sbostic #include <netccitt/x25.h> 3056530Sbostic #include <netccitt/pk.h> 3156530Sbostic #include <netccitt/pk_var.h> 32*57024Ssklower #include <netccitt/llc_var.h> 3341591Ssklower 34*57024Ssklower struct pkcb_q pkcb_q = {&pkcb_q, &pkcb_q}; 35*57024Ssklower 36*57024Ssklower /* 37*57024Ssklower * ccittintr() is the generic interrupt handler for HDLC, LLC2, and X.25. This 38*57024Ssklower * allows to have kernel running X.25 but no HDLC or LLC2 or both (in case we 39*57024Ssklower * employ boards that do all the stuff themselves, e.g. ADAX X.25 or TPS ISDN.) 40*57024Ssklower */ 41*57024Ssklower void 42*57024Ssklower ccittintr() 43*57024Ssklower { 44*57024Ssklower extern struct ifqueue pkintrq; 45*57024Ssklower extern struct ifqueue hdintrq; 46*57024Ssklower extern struct ifqueue llcintrq; 47*57024Ssklower 48*57024Ssklower #ifdef HDLC 49*57024Ssklower if (hdintrq.ifq_len) 50*57024Ssklower hdintr (); 51*57024Ssklower #endif 52*57024Ssklower #ifdef LLC 53*57024Ssklower if (llcintrq.ifq_len) 54*57024Ssklower llcintr (); 55*57024Ssklower #endif 56*57024Ssklower if (pkintrq.ifq_len) 57*57024Ssklower pkintr (); 58*57024Ssklower } 59*57024Ssklower 6049930Ssklower struct pkcb * 6149930Ssklower pk_newlink (ia, llnext) 6249930Ssklower struct x25_ifaddr *ia; 6349930Ssklower caddr_t llnext; 6449930Ssklower { 6549930Ssklower register struct x25config *xcp = &ia->ia_xc; 6649930Ssklower register struct pkcb *pkp; 6749930Ssklower register struct pklcd *lcp; 6849930Ssklower register struct protosw *pp; 6949930Ssklower unsigned size; 7049930Ssklower 7149930Ssklower pp = pffindproto (AF_CCITT, (int)xcp -> xc_lproto, 0); 7249930Ssklower if (pp == 0 || pp -> pr_output == 0) { 7349930Ssklower pk_message (0, xcp, "link level protosw error"); 7449930Ssklower return ((struct pkcb *)0); 7549930Ssklower } 7649930Ssklower /* 7749930Ssklower * Allocate a network control block structure 7849930Ssklower */ 7949930Ssklower size = sizeof (struct pkcb); 8049930Ssklower pkp = (struct pkcb *)malloc(size, M_PCB, M_WAITOK); 8149930Ssklower if (pkp == 0) 8249930Ssklower return ((struct pkcb *)0); 8349930Ssklower bzero ((caddr_t)pkp, size); 8449930Ssklower pkp -> pk_lloutput = pp -> pr_output; 85*57024Ssklower pkp -> pk_llctlinput = (caddr_t (*)())pp -> pr_ctlinput; 8649930Ssklower pkp -> pk_xcp = xcp; 8749930Ssklower pkp -> pk_ia = ia; 8849930Ssklower pkp -> pk_state = DTE_WAITING; 8949930Ssklower pkp -> pk_llnext = llnext; 90*57024Ssklower insque(pkp, &pkcb_q); 9149930Ssklower 9249930Ssklower /* 9349930Ssklower * set defaults 9449930Ssklower */ 9549930Ssklower 9649930Ssklower if (xcp -> xc_pwsize == 0) 9749930Ssklower xcp -> xc_pwsize = DEFAULT_WINDOW_SIZE; 9849930Ssklower if (xcp -> xc_psize == 0) 9949930Ssklower xcp -> xc_psize = X25_PS128; 10049930Ssklower /* 10149930Ssklower * Allocate logical channel descriptor vector 10249930Ssklower */ 10349930Ssklower 10449930Ssklower (void)pk_resize(pkp); 10549930Ssklower return (pkp); 10649930Ssklower } 10749930Ssklower 108*57024Ssklower 109*57024Ssklower pk_dellink (pkp) 110*57024Ssklower register struct pkcb *pkp; 111*57024Ssklower { 112*57024Ssklower register int i; 113*57024Ssklower register struct protosw *pp; 114*57024Ssklower 115*57024Ssklower /* 116*57024Ssklower * Essentially we have the choice to 117*57024Ssklower * (a) go ahead and let the route be deleted and 118*57024Ssklower * leave the pkcb associated with that route 119*57024Ssklower * as it is, i.e. the connections stay open 120*57024Ssklower * (b) do a pk_disconnect() on all channels associated 121*57024Ssklower * with the route via the pkcb and then proceed. 122*57024Ssklower * 123*57024Ssklower * For the time being we stick with (b) 124*57024Ssklower */ 125*57024Ssklower 126*57024Ssklower for(i = 1; i < pkp->pk_maxlcn; ++i) 127*57024Ssklower if (pkp->pk_chan[i]) 128*57024Ssklower pk_disconnect(pkp->pk_chan[i]); 129*57024Ssklower 130*57024Ssklower /* 131*57024Ssklower * Free the pkcb 132*57024Ssklower */ 133*57024Ssklower 134*57024Ssklower /* 135*57024Ssklower * First find the protoswitch to get hold of the link level 136*57024Ssklower * protocol to be notified that the packet level entity is 137*57024Ssklower * dissolving ... 138*57024Ssklower */ 139*57024Ssklower pp = pffindproto (AF_CCITT, (int)pkp ->pk_xcp -> xc_lproto, 0); 140*57024Ssklower if (pp == 0 || pp -> pr_output == 0) { 141*57024Ssklower pk_message (0, pkp -> pk_xcp, "link level protosw error"); 142*57024Ssklower return(EPROTONOSUPPORT); 143*57024Ssklower } 144*57024Ssklower 145*57024Ssklower pkp -> pk_refcount--; 146*57024Ssklower if (!pkp -> pk_refcount) { 147*57024Ssklower struct dll_ctlinfo ctlinfo; 148*57024Ssklower 149*57024Ssklower remque(pkp); 150*57024Ssklower if (pkp -> pk_rt -> rt_llinfo == (caddr_t) pkp) 151*57024Ssklower pkp -> pk_rt -> rt_llinfo = (caddr_t) NULL; 152*57024Ssklower 153*57024Ssklower /* 154*57024Ssklower * Tell the link level that the pkcb is dissolving 155*57024Ssklower */ 156*57024Ssklower if (pp -> pr_ctlinput && pkp -> pk_llnext) { 157*57024Ssklower ctlinfo.dlcti_pcb = pkp -> pk_llnext; 158*57024Ssklower ctlinfo.dlcti_rt = pkp -> pk_rt; 159*57024Ssklower (pp -> pr_ctlinput)(PRC_DISCONNECT_REQUEST, 160*57024Ssklower pkp -> pk_xcp, &ctlinfo); 161*57024Ssklower } 162*57024Ssklower free((caddr_t) pkp -> pk_chan, M_IFADDR); 163*57024Ssklower free((caddr_t) pkp, M_PCB); 164*57024Ssklower } 165*57024Ssklower 166*57024Ssklower return (0); 167*57024Ssklower } 168*57024Ssklower 169*57024Ssklower 17049930Ssklower pk_resize (pkp) 17149930Ssklower register struct pkcb *pkp; 17249930Ssklower { 17349930Ssklower struct pklcd *dev_lcp = 0; 17449930Ssklower struct x25config *xcp = pkp -> pk_xcp; 17549930Ssklower if (pkp -> pk_chan && 17649930Ssklower (pkp -> pk_maxlcn != xcp -> xc_maxlcn)) { 17749930Ssklower pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION); 17849930Ssklower dev_lcp = pkp -> pk_chan[0]; 17949930Ssklower free ((caddr_t)pkp -> pk_chan, M_IFADDR); 18049930Ssklower pkp -> pk_chan = 0; 18149930Ssklower } 18249930Ssklower if (pkp -> pk_chan == 0) { 18349930Ssklower unsigned size; 18449930Ssklower pkp -> pk_maxlcn = xcp -> xc_maxlcn; 18549930Ssklower size = (pkp -> pk_maxlcn + 1) * sizeof (struct pklcd *); 18649930Ssklower pkp -> pk_chan = 18749930Ssklower (struct pklcd **) malloc (size, M_IFADDR, M_WAITOK); 18849930Ssklower if (pkp -> pk_chan) { 18949930Ssklower bzero ((caddr_t)pkp -> pk_chan, size); 19049930Ssklower /* 19149930Ssklower * Allocate a logical channel descriptor for lcn 0 19249930Ssklower */ 19349930Ssklower if (dev_lcp == 0 && 19449930Ssklower (dev_lcp = pk_attach ((struct socket *)0)) == 0) 19549930Ssklower return (ENOBUFS); 19649930Ssklower dev_lcp -> lcd_state = READY; 19749930Ssklower dev_lcp -> lcd_pkp = pkp; 19849930Ssklower pkp -> pk_chan[0] = dev_lcp; 19949930Ssklower } else { 20049930Ssklower if (dev_lcp) 20149930Ssklower pk_close (dev_lcp); 20249930Ssklower return (ENOBUFS); 20349930Ssklower } 20449930Ssklower } 20549930Ssklower return 0; 20649930Ssklower } 20749930Ssklower 20841591Ssklower /* 20941591Ssklower * This procedure is called by the link level whenever the link 21041591Ssklower * becomes operational, is reset, or when the link goes down. 21141591Ssklower */ 212*57024Ssklower /*VARARGS*/ 213*57024Ssklower caddr_t 214*57024Ssklower pk_ctlinput (code, src, addr) 215*57024Ssklower struct sockaddr *src; 216*57024Ssklower caddr_t addr; 21741591Ssklower { 218*57024Ssklower register struct pkcb *pkp = (struct pkcb *)addr; 21941591Ssklower 22041591Ssklower switch (code) { 22141591Ssklower case PRC_LINKUP: 22241591Ssklower if (pkp -> pk_state == DTE_WAITING) 22341591Ssklower pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION); 22441591Ssklower break; 22541591Ssklower 22641591Ssklower case PRC_LINKDOWN: 22741591Ssklower pk_restart (pkp, -1); /* Clear all active circuits */ 22841591Ssklower pkp -> pk_state = DTE_WAITING; 22941591Ssklower break; 23041591Ssklower 23141591Ssklower case PRC_LINKRESET: 23241591Ssklower pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION); 23341591Ssklower break; 234*57024Ssklower 235*57024Ssklower case PRC_CONNECT_INDICATION: { 236*57024Ssklower struct rtentry *llrt; 23741591Ssklower 238*57024Ssklower if ((llrt = rtalloc1(src, 0)) == 0) 239*57024Ssklower return 0; 240*57024Ssklower else llrt->rt_refcnt--; 241*57024Ssklower 242*57024Ssklower pkp = (((struct npaidbentry *)llrt->rt_llinfo)->np_rt) ? 243*57024Ssklower (struct pkcb *)(((struct npaidbentry *)llrt->rt_llinfo)->np_rt->rt_llinfo) : (struct pkcb *) 0; 244*57024Ssklower if (pkp == (struct pkcb *) 0) 245*57024Ssklower return 0; 246*57024Ssklower pkp->pk_llnext = addr; 247*57024Ssklower 248*57024Ssklower return ((caddr_t) pkp); 24941591Ssklower } 250*57024Ssklower case PRC_DISCONNECT_INDICATION: 251*57024Ssklower pk_restart (pkp, -1) ; /* Clear all active circuits */ 252*57024Ssklower pkp->pk_state = DTE_WAITING; 253*57024Ssklower pkp->pk_llnext = (caddr_t) 0; 254*57024Ssklower } 25541591Ssklower return (0); 25641591Ssklower } 25745297Ssklower struct ifqueue pkintrq; 25845297Ssklower /* 25945297Ssklower * This routine is called if there are semi-smart devices that do HDLC 26045297Ssklower * in hardware and want to queue the packet and call level 3 directly 26145297Ssklower */ 26245297Ssklower pkintr () 26345297Ssklower { 26445297Ssklower register struct mbuf *m; 26545297Ssklower register struct ifaddr *ifa; 26645297Ssklower register struct ifnet *ifp; 26745297Ssklower register int s; 26841591Ssklower 26945297Ssklower for (;;) { 27045297Ssklower s = splimp (); 27145297Ssklower IF_DEQUEUE (&pkintrq, m); 27245297Ssklower splx (s); 27345297Ssklower if (m == 0) 27445297Ssklower break; 27545297Ssklower if (m->m_len < PKHEADERLN) { 27645297Ssklower printf ("pkintr: packet too short (len=%d)\n", 27745297Ssklower m->m_len); 27845297Ssklower m_freem (m); 27945297Ssklower continue; 28045297Ssklower } 28149930Ssklower pk_input(m); 28245297Ssklower } 28345297Ssklower } 28445297Ssklower struct mbuf *pk_bad_packet; 28549593Ssklower struct mbuf_cache pk_input_cache = {0 }; 28641591Ssklower /* 28741591Ssklower * X.25 PACKET INPUT 28841591Ssklower * 28941591Ssklower * This procedure is called by a link level procedure whenever 29041591Ssklower * an information frame is received. It decodes the packet and 29141591Ssklower * demultiplexes based on the logical channel number. 29241591Ssklower * 29349930Ssklower * We change the original conventions of the UBC code here -- 29449930Ssklower * since there may be multiple pkcb's for 802.2 class 2 29549930Ssklower * for a given interface, we must be informed which one it is; 29649930Ssklower * so we overwrite the pkthdr.rcvif; it can be recovered if necessary. 29749930Ssklower * 29841591Ssklower */ 29941591Ssklower 300*57024Ssklower #define RESTART_DTE_ORIGINATED(xp) (((xp) -> packet_cause == X25_RESTART_DTE_ORIGINATED) || \ 301*57024Ssklower ((xp) -> packet_cause >= X25_RESTART_DTE_ORIGINATED2)) 302*57024Ssklower 30349930Ssklower pk_input (m) 30441591Ssklower register struct mbuf *m; 30541591Ssklower { 30641591Ssklower register struct x25_packet *xp; 30741591Ssklower register struct pklcd *lcp; 30841591Ssklower register struct socket *so = 0; 30941591Ssklower register struct pkcb *pkp; 31041591Ssklower int ptype, lcn, lcdstate = LISTEN; 31141591Ssklower 31249593Ssklower if (pk_input_cache.mbc_size || pk_input_cache.mbc_oldsize) 31349593Ssklower mbuf_cache(&pk_input_cache, m); 31449930Ssklower if ((m->m_flags & M_PKTHDR) == 0) 31549930Ssklower panic("pkintr"); 316*57024Ssklower 31749930Ssklower if ((pkp = (struct pkcb *)m->m_pkthdr.rcvif) == 0) 31849930Ssklower return; 31941591Ssklower xp = mtod (m, struct x25_packet *); 32041591Ssklower ptype = pk_decode (xp); 32145573Ssklower lcn = LCN(xp); 32241591Ssklower lcp = pkp -> pk_chan[lcn]; 32341591Ssklower 32441591Ssklower /* 32541591Ssklower * If the DTE is in Restart state, then it will ignore data, 32641591Ssklower * interrupt, call setup and clearing, flow control and reset 32741591Ssklower * packets. 32841591Ssklower */ 32941591Ssklower if (lcn < 0 || lcn > pkp -> pk_maxlcn) { 33041591Ssklower pk_message (lcn, pkp -> pk_xcp, "illegal lcn"); 33141591Ssklower m_freem (m); 33241591Ssklower return; 33341591Ssklower } 33441591Ssklower 33545895Ssklower pk_trace (pkp -> pk_xcp, m, "P-In"); 33641591Ssklower 33741591Ssklower if (pkp -> pk_state != DTE_READY && ptype != RESTART && ptype != RESTART_CONF) { 33841591Ssklower m_freem (m); 33941591Ssklower return; 34041591Ssklower } 34141591Ssklower if (lcp) { 34241591Ssklower so = lcp -> lcd_so; 34341591Ssklower lcdstate = lcp -> lcd_state; 34441591Ssklower } else { 34541591Ssklower if (ptype == CLEAR) { /* idle line probe (Datapac specific) */ 34641591Ssklower /* send response on lcd 0's output queue */ 34749930Ssklower lcp = pkp -> pk_chan[0]; 34841591Ssklower lcp -> lcd_template = pk_template (lcn, X25_CLEAR_CONFIRM); 34941591Ssklower pk_output (lcp); 35041591Ssklower m_freem (m); 35141591Ssklower return; 35241591Ssklower } 35341591Ssklower if (ptype != CALL) 35441591Ssklower ptype = INVALID_PACKET; 35541591Ssklower } 35641591Ssklower 35741591Ssklower if (lcn == 0 && ptype != RESTART && ptype != RESTART_CONF) { 35845297Ssklower pk_message (0, pkp -> pk_xcp, "illegal ptype (%d, %s) on lcn 0", 35945297Ssklower ptype, pk_name[ptype / MAXSTATES]); 36045297Ssklower if (pk_bad_packet) 36145297Ssklower m_freem (pk_bad_packet); 36245297Ssklower pk_bad_packet = m; 36341591Ssklower return; 36441591Ssklower } 36541591Ssklower 36641591Ssklower switch (ptype + lcdstate) { 36741591Ssklower /* 36841591Ssklower * Incoming Call packet received. 36941591Ssklower */ 37041591Ssklower case CALL + LISTEN: 37149593Ssklower pk_incoming_call (pkp, m); 37241591Ssklower break; 37341591Ssklower 37441591Ssklower /* 37541591Ssklower * Call collision: Just throw this "incoming call" away since 37641591Ssklower * the DCE will ignore it anyway. 37741591Ssklower */ 37841591Ssklower case CALL + SENT_CALL: 37945573Ssklower pk_message ((int)lcn, pkp -> pk_xcp, 38041591Ssklower "incoming call collision"); 38141591Ssklower break; 38241591Ssklower 38341591Ssklower /* 38441591Ssklower * Call confirmation packet received. This usually means our 38541591Ssklower * previous connect request is now complete. 38641591Ssklower */ 38741591Ssklower case CALL_ACCEPTED + SENT_CALL: 38849252Ssklower MCHTYPE(m, MT_CONTROL); 38949593Ssklower pk_call_accepted (lcp, m); 39041591Ssklower break; 39141591Ssklower 39241591Ssklower /* 39341591Ssklower * This condition can only happen if the previous state was 39441591Ssklower * SENT_CALL. Just ignore the packet, eventually a clear 39541591Ssklower * confirmation should arrive. 39641591Ssklower */ 39741591Ssklower case CALL_ACCEPTED + SENT_CLEAR: 39841591Ssklower break; 39941591Ssklower 40041591Ssklower /* 40141591Ssklower * Clear packet received. This requires a complete tear down 40241591Ssklower * of the virtual circuit. Free buffers and control blocks. 40341591Ssklower * and send a clear confirmation. 40441591Ssklower */ 40541591Ssklower case CLEAR + READY: 40641591Ssklower case CLEAR + RECEIVED_CALL: 40741591Ssklower case CLEAR + SENT_CALL: 40841591Ssklower case CLEAR + DATA_TRANSFER: 40941591Ssklower lcp -> lcd_state = RECEIVED_CLEAR; 41041591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CLEAR_CONFIRM); 41141591Ssklower pk_output (lcp); 41241591Ssklower pk_clearcause (pkp, xp); 41349252Ssklower if (lcp -> lcd_upper) { 41449252Ssklower MCHTYPE(m, MT_CONTROL); 41549252Ssklower lcp -> lcd_upper (lcp, m); 41649252Ssklower } 41741591Ssklower pk_close (lcp); 41849252Ssklower lcp = 0; 41941591Ssklower break; 42041591Ssklower 42141591Ssklower /* 42241591Ssklower * Clear collision: Treat this clear packet as a confirmation. 42341591Ssklower */ 42441591Ssklower case CLEAR + SENT_CLEAR: 42541591Ssklower pk_close (lcp); 42641591Ssklower break; 42741591Ssklower 42841591Ssklower /* 42941591Ssklower * Clear confirmation received. This usually means the virtual 43041591Ssklower * circuit is now completely removed. 43141591Ssklower */ 43241591Ssklower case CLEAR_CONF + SENT_CLEAR: 43341591Ssklower pk_close (lcp); 43441591Ssklower break; 43541591Ssklower 43641591Ssklower /* 43741591Ssklower * A clear confirmation on an unassigned logical channel - just 43841591Ssklower * ignore it. Note: All other packets on an unassigned channel 43941591Ssklower * results in a clear. 44041591Ssklower */ 44141591Ssklower case CLEAR_CONF + READY: 44249930Ssklower case CLEAR_CONF + LISTEN: 44341591Ssklower break; 44441591Ssklower 44541591Ssklower /* 44641591Ssklower * Data packet received. Pass on to next level. Move the Q and M 44741591Ssklower * bits into the data portion for the next level. 44841591Ssklower */ 44941591Ssklower case DATA + DATA_TRANSFER: 45041591Ssklower if (lcp -> lcd_reset_condition) { 45141591Ssklower ptype = DELETE_PACKET; 45241591Ssklower break; 45341591Ssklower } 45441591Ssklower 45541591Ssklower /* 45641591Ssklower * Process the P(S) flow control information in this Data packet. 45741591Ssklower * Check that the packets arrive in the correct sequence and that 45841591Ssklower * they are within the "lcd_input_window". Input window rotation is 45941591Ssklower * initiated by the receive interface. 46041591Ssklower */ 46141591Ssklower 46241591Ssklower if (PS(xp) != ((lcp -> lcd_rsn + 1) % MODULUS) || 46341591Ssklower PS(xp) == ((lcp -> lcd_input_window + lcp->lcd_windowsize) % MODULUS)) { 46441591Ssklower m_freem (m); 46545895Ssklower pk_procerror (RESET, lcp, "p(s) flow control error", 1); 46641591Ssklower break; 46741591Ssklower } 46841591Ssklower lcp -> lcd_rsn = PS(xp); 46941591Ssklower 47041591Ssklower if (pk_ack (lcp, PR(xp)) != PACKET_OK) { 47141591Ssklower m_freem (m); 47241591Ssklower break; 47341591Ssklower } 47445895Ssklower m -> m_data += PKHEADERLN; 47545895Ssklower m -> m_len -= PKHEADERLN; 47645895Ssklower m -> m_pkthdr.len -= PKHEADERLN; 47745895Ssklower 47849930Ssklower lcp -> lcd_rxcnt++; 47945895Ssklower if (lcp -> lcd_flags & X25_MBS_HOLD) { 48045895Ssklower register struct mbuf *n = lcp -> lcd_cps; 48145895Ssklower int mbit = MBIT(xp); 48245895Ssklower octet q_and_d_bits; 48345895Ssklower 48445895Ssklower if (n) { 48545895Ssklower n -> m_pkthdr.len += m -> m_pkthdr.len; 48645895Ssklower while (n -> m_next) 48745895Ssklower n = n -> m_next; 48845895Ssklower n -> m_next = m; 48945895Ssklower m = lcp -> lcd_cps; 49045895Ssklower 49145895Ssklower if (lcp -> lcd_cpsmax && 49245895Ssklower n -> m_pkthdr.len > lcp -> lcd_cpsmax) { 49345895Ssklower pk_procerror (RESET, lcp, 49445895Ssklower "C.P.S. overflow", 128); 49545895Ssklower return; 49645895Ssklower } 49745895Ssklower q_and_d_bits = 0xc0 & *(octet *)xp; 49845895Ssklower xp = (struct x25_packet *) 49945895Ssklower (mtod(m, octet *) - PKHEADERLN); 50045895Ssklower *(octet *)xp |= q_and_d_bits; 50145895Ssklower } 50245895Ssklower if (mbit) { 50345895Ssklower lcp -> lcd_cps = m; 50447268Ssklower pk_flowcontrol(lcp, 0, 1); 50545895Ssklower return; 50645895Ssklower } 50745895Ssklower lcp -> lcd_cps = 0; 50845895Ssklower } 50945297Ssklower if (so == 0) 51045297Ssklower break; 51141591Ssklower if (lcp -> lcd_flags & X25_MQBIT) { 512*57024Ssklower octet t = (X25GBITS(xp -> bits, q_bit)) ? t = 0x80 : 0; 51341591Ssklower 51445573Ssklower if (MBIT(xp)) 51545573Ssklower t |= 0x40; 51643361Ssklower m -> m_data -= 1; 51741591Ssklower m -> m_len += 1; 51845895Ssklower m -> m_pkthdr.len += 1; 51945573Ssklower *mtod(m, octet *) = t; 52041591Ssklower } 52141591Ssklower 52241591Ssklower /* 52341591Ssklower * Discard Q-BIT packets if the application 52441591Ssklower * doesn't want to be informed of M and Q bit status 52541591Ssklower */ 526*57024Ssklower if (X25GBITS(xp -> bits, q_bit) 527*57024Ssklower && (lcp -> lcd_flags & X25_MQBIT) == 0) { 52841591Ssklower m_freem (m); 52941591Ssklower /* 53041591Ssklower * NB. This is dangerous: sending a RR here can 53141591Ssklower * cause sequence number errors if a previous data 53241591Ssklower * packet has not yet been passed up to the application 53341591Ssklower * (RR's are normally generated via PRU_RCVD). 53441591Ssklower */ 53547268Ssklower pk_flowcontrol(lcp, 0, 1); 53641591Ssklower } else { 53741591Ssklower sbappendrecord (&so -> so_rcv, m); 53841591Ssklower sorwakeup (so); 53941591Ssklower } 54041591Ssklower break; 54141591Ssklower 54241591Ssklower /* 54341591Ssklower * Interrupt packet received. 54441591Ssklower */ 54541591Ssklower case INTERRUPT + DATA_TRANSFER: 54641591Ssklower if (lcp -> lcd_reset_condition) 54741591Ssklower break; 54841591Ssklower lcp -> lcd_intrdata = xp -> packet_data; 54941591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM); 55041591Ssklower pk_output (lcp); 55145895Ssklower m -> m_data += PKHEADERLN; 55245895Ssklower m -> m_len -= PKHEADERLN; 55345895Ssklower m -> m_pkthdr.len -= PKHEADERLN; 55445297Ssklower MCHTYPE(m, MT_OOBDATA); 55545895Ssklower if (so) { 55645895Ssklower if (so -> so_options & SO_OOBINLINE) 55745895Ssklower sbinsertoob (&so -> so_rcv, m); 55845895Ssklower else 55945895Ssklower m_freem (m); 56045297Ssklower sohasoutofband (so); 56145895Ssklower } 56241591Ssklower break; 56341591Ssklower 56441591Ssklower /* 56541591Ssklower * Interrupt confirmation packet received. 56641591Ssklower */ 56741591Ssklower case INTERRUPT_CONF + DATA_TRANSFER: 56841591Ssklower if (lcp -> lcd_reset_condition) 56941591Ssklower break; 57041591Ssklower if (lcp -> lcd_intrconf_pending == TRUE) 57141591Ssklower lcp -> lcd_intrconf_pending = FALSE; 57241591Ssklower else 57345895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 43); 57441591Ssklower break; 57541591Ssklower 57641591Ssklower /* 57741591Ssklower * Receiver ready received. Rotate the output window and output 57841591Ssklower * any data packets waiting transmission. 57941591Ssklower */ 58041591Ssklower case RR + DATA_TRANSFER: 58145297Ssklower if (lcp -> lcd_reset_condition || 58245297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 58345297Ssklower ptype = DELETE_PACKET; 58441591Ssklower break; 58545297Ssklower } 58641591Ssklower if (lcp -> lcd_rnr_condition == TRUE) 58741591Ssklower lcp -> lcd_rnr_condition = FALSE; 58841591Ssklower pk_output (lcp); 58941591Ssklower break; 59041591Ssklower 59141591Ssklower /* 59241591Ssklower * Receiver Not Ready received. Packets up to the P(R) can be 59341591Ssklower * be sent. Condition is cleared with a RR. 59441591Ssklower */ 59541591Ssklower case RNR + DATA_TRANSFER: 59645297Ssklower if (lcp -> lcd_reset_condition || 59745297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 59845297Ssklower ptype = DELETE_PACKET; 59941591Ssklower break; 60045297Ssklower } 60141591Ssklower lcp -> lcd_rnr_condition = TRUE; 60241591Ssklower break; 60341591Ssklower 60441591Ssklower /* 60541591Ssklower * Reset packet received. Set state to FLOW_OPEN. The Input and 60641591Ssklower * Output window edges ar set to zero. Both the send and receive 60741591Ssklower * numbers are reset. A confirmation is returned. 60841591Ssklower */ 60941591Ssklower case RESET + DATA_TRANSFER: 61041591Ssklower if (lcp -> lcd_reset_condition) 61141591Ssklower /* Reset collision. Just ignore packet. */ 61241591Ssklower break; 61341591Ssklower 61441591Ssklower pk_resetcause (pkp, xp); 61541591Ssklower lcp -> lcd_window_condition = lcp -> lcd_rnr_condition = 61641591Ssklower lcp -> lcd_intrconf_pending = FALSE; 61741591Ssklower lcp -> lcd_output_window = lcp -> lcd_input_window = 61841591Ssklower lcp -> lcd_last_transmitted_pr = 0; 61941591Ssklower lcp -> lcd_ssn = 0; 62041591Ssklower lcp -> lcd_rsn = MODULUS - 1; 62141591Ssklower 62241591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM); 62341591Ssklower pk_output (lcp); 62445297Ssklower 62545895Ssklower pk_flush(lcp); 62645297Ssklower if (so == 0) 62745297Ssklower break; 62845297Ssklower wakeup ((caddr_t) & so -> so_timeo); 62945297Ssklower sorwakeup (so); 63045297Ssklower sowwakeup (so); 63141591Ssklower break; 63241591Ssklower 63341591Ssklower /* 63441591Ssklower * Reset confirmation received. 63541591Ssklower */ 63641591Ssklower case RESET_CONF + DATA_TRANSFER: 63741591Ssklower if (lcp -> lcd_reset_condition) { 63841591Ssklower lcp -> lcd_reset_condition = FALSE; 63941591Ssklower pk_output (lcp); 64041591Ssklower } 64141591Ssklower else 64245895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 32); 64341591Ssklower break; 64441591Ssklower 64541591Ssklower case DATA + SENT_CLEAR: 64641591Ssklower ptype = DELETE_PACKET; 64741591Ssklower case RR + SENT_CLEAR: 64841591Ssklower case RNR + SENT_CLEAR: 64941591Ssklower case INTERRUPT + SENT_CLEAR: 65041591Ssklower case INTERRUPT_CONF + SENT_CLEAR: 65141591Ssklower case RESET + SENT_CLEAR: 65241591Ssklower case RESET_CONF + SENT_CLEAR: 65345297Ssklower /* Just ignore p if we have sent a CLEAR already. 65441591Ssklower */ 65541591Ssklower break; 65641591Ssklower 65741591Ssklower /* 65841591Ssklower * Restart sets all the permanent virtual circuits to the "Data 65941591Ssklower * Transfer" stae and all the switched virtual circuits to the 66041591Ssklower * "Ready" state. 66141591Ssklower */ 66241591Ssklower case RESTART + READY: 66341591Ssklower switch (pkp -> pk_state) { 66441591Ssklower case DTE_SENT_RESTART: 665*57024Ssklower /* 666*57024Ssklower * Restart collision. 667*57024Ssklower * If case the restart cause is "DTE originated" we 668*57024Ssklower * have a DTE-DTE situation and are trying to resolve 669*57024Ssklower * who is going to play DTE/DCE [ISO 8208:4.2-4.5] 670*57024Ssklower */ 671*57024Ssklower if (RESTART_DTE_ORIGINATED(xp)) { 672*57024Ssklower pk_restart (pkp, X25_RESTART_DTE_ORIGINATED); 673*57024Ssklower pk_message (0, pkp -> pk_xcp, 674*57024Ssklower "RESTART collision"); 675*57024Ssklower if ((pkp -> pk_restartcolls++) > MAXRESTARTCOLLISIONS) { 676*57024Ssklower pk_message (0, pkp -> pk_xcp, 677*57024Ssklower "excessive RESTART collisions"); 678*57024Ssklower pkp -> pk_restartcolls = 0; 679*57024Ssklower } 680*57024Ssklower break; 681*57024Ssklower } 68241591Ssklower pkp -> pk_state = DTE_READY; 683*57024Ssklower pkp -> pk_dxerole |= DTE_PLAYDTE; 684*57024Ssklower pkp -> pk_dxerole &= ~DTE_PLAYDCE; 68541591Ssklower pk_message (0, pkp -> pk_xcp, 68641591Ssklower "Packet level operational"); 687*57024Ssklower pk_message (0, pkp -> pk_xcp, 688*57024Ssklower "Assuming DTE role"); 689*57024Ssklower if (pkp -> pk_dxerole & DTE_CONNECTPENDING) 690*57024Ssklower pk_callcomplete(pkp); 69141591Ssklower break; 69241591Ssklower 69341591Ssklower default: 69441591Ssklower pk_restart (pkp, -1); 69541591Ssklower pk_restartcause (pkp, xp); 69641591Ssklower pkp -> pk_chan[0] -> lcd_template = pk_template (0, 69741591Ssklower X25_RESTART_CONFIRM); 69841591Ssklower pk_output (pkp -> pk_chan[0]); 699*57024Ssklower pkp -> pk_state = DTE_READY; 700*57024Ssklower pkp -> pk_dxerole |= RESTART_DTE_ORIGINATED(xp) ? DTE_PLAYDCE : 701*57024Ssklower DTE_PLAYDTE; 702*57024Ssklower if (pkp -> pk_dxerole & DTE_PLAYDTE) { 703*57024Ssklower pkp -> pk_dxerole &= ~DTE_PLAYDCE; 704*57024Ssklower pk_message (0, pkp -> pk_xcp, 705*57024Ssklower "Assuming DTE role"); 706*57024Ssklower } else { 707*57024Ssklower pkp -> pk_dxerole &= ~DTE_PLAYDTE; 708*57024Ssklower pk_message (0, pkp -> pk_xcp, 709*57024Ssklower "Assuming DCE role"); 710*57024Ssklower } 711*57024Ssklower if (pkp -> pk_dxerole & DTE_CONNECTPENDING) 712*57024Ssklower pk_callcomplete(pkp); 71341591Ssklower } 71441591Ssklower break; 71541591Ssklower 71641591Ssklower /* 71741591Ssklower * Restart confirmation received. All logical channels are set 71841591Ssklower * to READY. 71941591Ssklower */ 72041591Ssklower case RESTART_CONF + READY: 72141591Ssklower switch (pkp -> pk_state) { 72241591Ssklower case DTE_SENT_RESTART: 72341591Ssklower pkp -> pk_state = DTE_READY; 724*57024Ssklower pkp -> pk_dxerole |= DTE_PLAYDTE; 725*57024Ssklower pkp -> pk_dxerole &= ~DTE_PLAYDCE; 72641591Ssklower pk_message (0, pkp -> pk_xcp, 727*57024Ssklower "Packet level operational"); 728*57024Ssklower pk_message (0, pkp-> pk_xcp, 729*57024Ssklower "Assuming DTE role"); 730*57024Ssklower if (pkp -> pk_dxerole & DTE_CONNECTPENDING) 731*57024Ssklower pk_callcomplete(pkp); 73241591Ssklower break; 73341591Ssklower 73441591Ssklower default: 73541591Ssklower /* Restart local procedure error. */ 73641591Ssklower pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR); 73741591Ssklower pkp -> pk_state = DTE_SENT_RESTART; 738*57024Ssklower pkp -> pk_dxerole &= ~(DTE_PLAYDTE | DTE_PLAYDCE); 73941591Ssklower } 74041591Ssklower break; 74141591Ssklower 74241591Ssklower default: 74341591Ssklower if (lcp) { 74445895Ssklower pk_procerror (CLEAR, lcp, "unknown packet error", 33); 74541591Ssklower pk_message (lcn, pkp -> pk_xcp, 74641591Ssklower "\"%s\" unexpected in \"%s\" state", 74741591Ssklower pk_name[ptype/MAXSTATES], pk_state[lcdstate]); 74845895Ssklower } else 74945573Ssklower pk_message (lcn, pkp -> pk_xcp, 75041591Ssklower "packet arrived on unassigned lcn"); 75141591Ssklower break; 75241591Ssklower } 75349252Ssklower if (so == 0 && lcp && lcp -> lcd_upper && lcdstate == DATA_TRANSFER) { 75445895Ssklower if (ptype != DATA && ptype != INTERRUPT) 75545895Ssklower MCHTYPE(m, MT_CONTROL); 75645297Ssklower lcp -> lcd_upper (lcp, m); 75745895Ssklower } else if (ptype != DATA && ptype != INTERRUPT) 75841591Ssklower m_freem (m); 75941591Ssklower } 76041591Ssklower 76149930Ssklower static 76249930Ssklower prune_dnic(from, to, dnicname, xcp) 76349930Ssklower char *from, *to, *dnicname; 76449930Ssklower register struct x25config *xcp; 76549930Ssklower { 76649930Ssklower register char *cp1 = from, *cp2 = from; 76749930Ssklower if (xcp->xc_prepnd0 && *cp1 == '0') { 76849930Ssklower from = ++cp1; 76949930Ssklower goto copyrest; 77049930Ssklower } 77149930Ssklower if (xcp->xc_nodnic) { 77249930Ssklower for (cp1 = dnicname; *cp2 = *cp1++;) 77349930Ssklower cp2++; 77449930Ssklower cp1 = from; 77549930Ssklower } 77649930Ssklower copyrest: 77749930Ssklower for (cp1 = dnicname; *cp2 = *cp1++;) 77849930Ssklower cp2++; 77949930Ssklower } 78049930Ssklower /* static */ 78149930Ssklower pk_simple_bsd (from, to, lower, len) 78249930Ssklower register octet *from, *to; 78349930Ssklower register len, lower; 78449930Ssklower { 78549930Ssklower register int c; 78649930Ssklower while (--len >= 0) { 78749930Ssklower c = *from; 78849930Ssklower if (lower & 0x01) 78949930Ssklower *from++; 79049930Ssklower else 79149930Ssklower c >>= 4; 79249930Ssklower c &= 0x0f; c |= 0x30; *to++ = c; lower++; 79349930Ssklower } 79449930Ssklower *to = 0; 79549930Ssklower } 79641591Ssklower 79749930Ssklower /*static octet * */ 79849930Ssklower pk_from_bcd (a, iscalling, sa, xcp) 79949930Ssklower register struct x25_calladdr *a; 80049930Ssklower register struct sockaddr_x25 *sa; 80149930Ssklower register struct x25config *xcp; 80249930Ssklower { 80349930Ssklower octet buf[MAXADDRLN+1]; 80449930Ssklower octet *cp; 80549930Ssklower unsigned count; 80649930Ssklower 80749930Ssklower bzero ((caddr_t)sa, sizeof (*sa)); 80849930Ssklower sa -> x25_len = sizeof (*sa); 80949930Ssklower sa -> x25_family = AF_CCITT; 81049930Ssklower if (iscalling) { 811*57024Ssklower cp = a -> address_field + (X25GBITS(a -> addrlens, called_addrlen) / 2); 812*57024Ssklower count = X25GBITS(a -> addrlens, calling_addrlen); 813*57024Ssklower pk_simple_bsd (cp, buf, X25GBITS(a -> addrlens, called_addrlen), count); 81449930Ssklower } else { 815*57024Ssklower count = X25GBITS(a -> addrlens, called_addrlen); 81649930Ssklower pk_simple_bsd (a -> address_field, buf, 0, count); 81749930Ssklower } 81849930Ssklower if (xcp -> xc_addr.x25_net && (xcp -> xc_nodnic || xcp ->xc_prepnd0)) { 81949930Ssklower octet dnicname[sizeof(long) * NBBY/3 + 2]; 82049930Ssklower 821*57024Ssklower sprintf ((char *) dnicname, "%d", xcp -> xc_addr.x25_net); 822*57024Ssklower prune_dnic ((char *)buf, sa -> x25_addr, dnicname, xcp); 82349930Ssklower } else 82449930Ssklower bcopy ((caddr_t)buf, (caddr_t)sa -> x25_addr, count + 1); 82549930Ssklower } 82649930Ssklower 82749930Ssklower static 82849930Ssklower save_extra(m0, fp, so) 82949930Ssklower struct mbuf *m0; 83049930Ssklower octet *fp; 83149930Ssklower struct socket *so; 83249930Ssklower { 83349930Ssklower register struct mbuf *m; 83449930Ssklower struct cmsghdr cmsghdr; 83552449Ssklower if (m = m_copy (m, 0, (int)M_COPYALL)) { 83649930Ssklower int off = fp - mtod (m0, octet *); 83749930Ssklower int len = m->m_pkthdr.len - off + sizeof (cmsghdr); 83849930Ssklower cmsghdr.cmsg_len = len; 83949930Ssklower cmsghdr.cmsg_level = AF_CCITT; 84049930Ssklower cmsghdr.cmsg_type = PK_FACILITIES; 84149930Ssklower m_adj (m, off); 84249930Ssklower M_PREPEND (m, sizeof(cmsghdr), M_DONTWAIT); 84349930Ssklower if (m == 0) 84449930Ssklower return; 84549930Ssklower bcopy ((caddr_t)&cmsghdr, mtod (m, caddr_t), sizeof (cmsghdr)); 84649930Ssklower MCHTYPE(m, MT_CONTROL); 84749930Ssklower sbappendrecord(&so -> so_rcv, m); 84849930Ssklower } 84949930Ssklower } 85049930Ssklower 85141591Ssklower /* 85241591Ssklower * This routine handles incoming call packets. It matches the protocol 85341591Ssklower * field on the Call User Data field (usually the first four bytes) with 85441591Ssklower * sockets awaiting connections. 85541591Ssklower */ 85641591Ssklower 85749593Ssklower pk_incoming_call (pkp, m0) 85845895Ssklower struct mbuf *m0; 85941591Ssklower struct pkcb *pkp; 86041591Ssklower { 86142277Ssklower register struct pklcd *lcp = 0, *l; 86241591Ssklower register struct sockaddr_x25 *sa; 86341591Ssklower register struct x25_calladdr *a; 86442277Ssklower register struct socket *so = 0; 86549930Ssklower struct x25_packet *xp = mtod(m0, struct x25_packet *); 86649930Ssklower struct mbuf *m; 86749930Ssklower struct x25config *xcp = pkp -> pk_xcp; 86845895Ssklower int len = m0->m_pkthdr.len; 86949930Ssklower unsigned udlen; 87049930Ssklower char *errstr = "server unavailable"; 87145895Ssklower octet *u, *facp; 87245573Ssklower int lcn = LCN(xp); 87341591Ssklower 87449930Ssklower /* First, copy the data from the incoming call packet to a X25 address 87549930Ssklower descriptor. It is to be regretted that you have 87649930Ssklower to parse the facilities into a sockaddr to determine 87749930Ssklower if reverse charging is being requested */ 87849930Ssklower if ((m = m_get (M_DONTWAIT, MT_SONAME)) == 0) 87941591Ssklower return; 88041591Ssklower sa = mtod (m, struct sockaddr_x25 *); 88149930Ssklower a = (struct x25_calladdr *) &xp -> packet_data; 88249930Ssklower facp = u = (octet *) (a -> address_field + 883*57024Ssklower ((X25GBITS(a -> addrlens, called_addrlen) + X25GBITS(a -> addrlens, calling_addrlen) + 1) / 2)); 88449930Ssklower u += *u + 1; 88549930Ssklower udlen = min (16, ((octet *)xp) + len - u); 88649930Ssklower if (udlen < 0) 88749930Ssklower udlen = 0; 88849930Ssklower pk_from_bcd (a, 1, sa, pkp -> pk_xcp); /* get calling address */ 88950426Ssklower pk_parse_facilities (facp, sa); 89049930Ssklower bcopy ((caddr_t)u, sa -> x25_udata, udlen); 89149930Ssklower sa -> x25_udlen = udlen; 89241591Ssklower 89341591Ssklower /* 89450426Ssklower * Now, loop through the listen sockets looking for a match on the 89550426Ssklower * PID. That is the first few octets of the user data field. 89650426Ssklower * This is the closest thing to a port number for X.25 packets. 89750426Ssklower * It does provide a way of multiplexing services at the user level. 89841591Ssklower */ 89941591Ssklower 90041591Ssklower for (l = pk_listenhead; l; l = l -> lcd_listen) { 90141591Ssklower struct sockaddr_x25 *sxp = l -> lcd_ceaddr; 90241591Ssklower 90349930Ssklower if (bcmp (sxp -> x25_udata, u, sxp->x25_udlen)) 90441591Ssklower continue; 90545165Ssklower if (sxp -> x25_net && 90649930Ssklower sxp -> x25_net != xcp -> xc_addr.x25_net) 90741591Ssklower continue; 90841591Ssklower /* 90949930Ssklower * don't accept incoming calls with the D-Bit on 91049930Ssklower * unless the server agrees 91149930Ssklower */ 912*57024Ssklower if (X25GBITS(xp -> bits, d_bit) && !(sxp -> x25_opts.op_flags & X25_DBIT)) { 91349930Ssklower errstr = "incoming D-Bit mismatch"; 91449930Ssklower break; 91549930Ssklower } 91649930Ssklower /* 91741591Ssklower * don't accept incoming collect calls unless 91841591Ssklower * the server sets the reverse charging option. 91941591Ssklower */ 92041591Ssklower if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 && 92141591Ssklower sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) { 92241591Ssklower errstr = "incoming collect call refused"; 92341591Ssklower break; 92441591Ssklower } 92542277Ssklower if (l -> lcd_so) { 92645165Ssklower if (so = sonewconn (l -> lcd_so, SS_ISCONNECTED)) 92742277Ssklower lcp = (struct pklcd *) so -> so_pcb; 92842277Ssklower } else 92942277Ssklower lcp = pk_attach((struct socket *) 0); 93042277Ssklower if (lcp == 0) { 93141591Ssklower /* 93241591Ssklower * Insufficient space or too many unaccepted 93341591Ssklower * connections. Just throw the call away. 93441591Ssklower */ 93541591Ssklower errstr = "server malfunction"; 93641591Ssklower break; 93741591Ssklower } 93843361Ssklower lcp -> lcd_upper = l -> lcd_upper; 93943361Ssklower lcp -> lcd_upnext = l -> lcd_upnext; 94041591Ssklower lcp -> lcd_lcn = lcn; 94141591Ssklower lcp -> lcd_state = RECEIVED_CALL; 94250020Ssklower sa -> x25_opts.op_flags |= (sxp -> x25_opts.op_flags & 94350020Ssklower ~X25_REVERSE_CHARGE) | l -> lcd_flags; 94441591Ssklower pk_assoc (pkp, lcp, sa); 94549930Ssklower lcp -> lcd_faddr = *sa; 94649930Ssklower lcp -> lcd_laddr.x25_udlen = sxp -> x25_udlen; 94749930Ssklower lcp -> lcd_craddr = &lcp->lcd_faddr; 94841591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED); 94945573Ssklower if (lcp -> lcd_flags & X25_DBIT) { 950*57024Ssklower if (X25GBITS(xp -> bits, d_bit)) 951*57024Ssklower X25SBITS(mtod(lcp -> lcd_template, 952*57024Ssklower struct x25_packet *) -> bits, d_bit, 1); 95345573Ssklower else 95445573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 95545573Ssklower } 95643361Ssklower if (so) { 95743361Ssklower pk_output (lcp); 95842277Ssklower soisconnected (so); 95945895Ssklower if (so -> so_options & SO_OOBINLINE) 96045895Ssklower save_extra(m0, facp, so); 96145895Ssklower } else if (lcp -> lcd_upper) { 96249930Ssklower (*lcp -> lcd_upper) (lcp, m0); 96345895Ssklower } 96449930Ssklower (void) m_free (m); 96541591Ssklower return; 96641591Ssklower } 96741591Ssklower 96841591Ssklower /* 96941591Ssklower * If the call fails for whatever reason, we still need to build a 97041591Ssklower * skeleton LCD in order to be able to properly receive the CLEAR 97141591Ssklower * CONFIRMATION. 97241591Ssklower */ 97341591Ssklower #ifdef WATERLOO /* be explicit */ 97441591Ssklower if (l == 0 && bcmp(sa->x25_udata, "ean", 3) == 0) 97541591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s", 97641591Ssklower sa->x25_addr, sa->x25_udata[3] & 0xff, errstr); 97741591Ssklower else if (l == 0 && bcmp(sa->x25_udata, "\1\0\0\0", 4) == 0) 97841591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s", 97941591Ssklower sa->x25_addr, errstr); 98041591Ssklower else 98141591Ssklower #endif 98241591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s", 98341591Ssklower sa -> x25_addr, sa -> x25_udata[0] & 0xff, 98441591Ssklower sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff, 98541591Ssklower sa -> x25_udata[3] & 0xff, errstr); 98645297Ssklower if ((lcp = pk_attach((struct socket *)0)) == 0) { 98745297Ssklower (void) m_free (m); 98841591Ssklower return; 98941591Ssklower } 99041591Ssklower lcp -> lcd_lcn = lcn; 99141591Ssklower lcp -> lcd_state = RECEIVED_CALL; 99241591Ssklower pk_assoc (pkp, lcp, sa); 99345297Ssklower (void) m_free (m); 99445895Ssklower pk_clear (lcp, 0, 1); 99541591Ssklower } 99641591Ssklower 99749593Ssklower pk_call_accepted (lcp, m) 99841591Ssklower struct pklcd *lcp; 99949252Ssklower struct mbuf *m; 100041591Ssklower { 100141591Ssklower register struct x25_calladdr *ap; 100241591Ssklower register octet *fcp; 100349252Ssklower struct x25_packet *xp = mtod (m, struct x25_packet *); 100449252Ssklower int len = m -> m_len; 100541591Ssklower 100641591Ssklower lcp -> lcd_state = DATA_TRANSFER; 100745297Ssklower if (lcp -> lcd_so) 100845297Ssklower soisconnected (lcp -> lcd_so); 1009*57024Ssklower if ((lcp -> lcd_flags & X25_DBIT) && (X25GBITS(xp -> bits, d_bit) == 0)) 101045573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 101141591Ssklower if (len > 3) { 101241591Ssklower ap = (struct x25_calladdr *) &xp -> packet_data; 1013*57024Ssklower fcp = (octet *) ap -> address_field + (X25GBITS(ap -> addrlens, calling_addrlen) + 1014*57024Ssklower X25GBITS(ap -> addrlens, called_addrlen) + 1) / 2; 101541591Ssklower if (fcp + *fcp <= ((octet *)xp) + len) 101649593Ssklower pk_parse_facilities (fcp, lcp -> lcd_ceaddr); 101741591Ssklower } 101841591Ssklower pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr); 101949252Ssklower if (lcp -> lcd_so == 0 && lcp -> lcd_upper) 102049252Ssklower lcp -> lcd_upper(lcp, m); 102141591Ssklower } 102241591Ssklower 102349593Ssklower pk_parse_facilities (fcp, sa) 102441591Ssklower register octet *fcp; 102541591Ssklower register struct sockaddr_x25 *sa; 102641591Ssklower { 102741591Ssklower register octet *maxfcp; 102841591Ssklower 102941591Ssklower maxfcp = fcp + *fcp; 103041591Ssklower fcp++; 103141591Ssklower while (fcp < maxfcp) { 103241591Ssklower /* 103341591Ssklower * Ignore national DCE or DTE facilities 103441591Ssklower */ 103541591Ssklower if (*fcp == 0 || *fcp == 0xff) 103641591Ssklower break; 103741591Ssklower switch (*fcp) { 103841591Ssklower case FACILITIES_WINDOWSIZE: 103941591Ssklower sa -> x25_opts.op_wsize = fcp[1]; 104041591Ssklower fcp += 3; 104141591Ssklower break; 104241591Ssklower 104341591Ssklower case FACILITIES_PACKETSIZE: 104441591Ssklower sa -> x25_opts.op_psize = fcp[1]; 104541591Ssklower fcp += 3; 104641591Ssklower break; 104741591Ssklower 104841591Ssklower case FACILITIES_THROUGHPUT: 104941591Ssklower sa -> x25_opts.op_speed = fcp[1]; 105041591Ssklower fcp += 2; 105141591Ssklower break; 105241591Ssklower 105341591Ssklower case FACILITIES_REVERSE_CHARGE: 105441591Ssklower if (fcp[1] & 01) 105541591Ssklower sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE; 105641591Ssklower /* 105741591Ssklower * Datapac specific: for a X.25(1976) DTE, bit 2 105841591Ssklower * indicates a "hi priority" (eg. international) call. 105941591Ssklower */ 106041591Ssklower if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0) 106141591Ssklower sa -> x25_opts.op_psize = X25_PS128; 106241591Ssklower fcp += 2; 106341591Ssklower break; 106441591Ssklower 106541591Ssklower default: 106641591Ssklower /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/ 106741591Ssklower switch ((*fcp & 0xc0) >> 6) { 106841591Ssklower case 0: /* class A */ 106941591Ssklower fcp += 2; 107041591Ssklower break; 107141591Ssklower 107241591Ssklower case 1: 107341591Ssklower fcp += 3; 107441591Ssklower break; 107541591Ssklower 107641591Ssklower case 2: 107741591Ssklower fcp += 4; 107841591Ssklower break; 107941591Ssklower 108041591Ssklower case 3: 108141591Ssklower fcp++; 108241591Ssklower fcp += *fcp; 108341591Ssklower } 108441591Ssklower } 108541591Ssklower } 108641591Ssklower } 1087