141709Ssklower /* 241709Ssklower * Copyright (c) University of British Columbia, 1984 341709Ssklower * Copyright (c) 1990 The Regents of the University of California. 441709Ssklower * All rights reserved. 541709Ssklower * 641709Ssklower * This code is derived from software contributed to Berkeley by 741709Ssklower * the Laboratory for Computation Vision and the Computer Science Department 841709Ssklower * of the University of British Columbia. 941709Ssklower * 1041709Ssklower * %sccs.include.redist.c% 1141709Ssklower * 12*45895Ssklower * @(#)pk_input.c 7.8 (Berkeley) 01/09/91 1341709Ssklower */ 1441591Ssklower 1545165Ssklower #include "param.h" 1645165Ssklower #include "systm.h" 1745165Ssklower #include "mbuf.h" 1845165Ssklower #include "socket.h" 1945165Ssklower #include "protosw.h" 2045165Ssklower #include "socketvar.h" 2145165Ssklower #include "errno.h" 2241591Ssklower 2341591Ssklower #include "../net/if.h" 2441591Ssklower 2545165Ssklower #include "x25.h" 2645165Ssklower #include "pk.h" 2745165Ssklower #include "pk_var.h" 2841591Ssklower 2941591Ssklower /* 3041591Ssklower * This procedure is called by the link level whenever the link 3141591Ssklower * becomes operational, is reset, or when the link goes down. 3241591Ssklower */ 3341591Ssklower 3445297Ssklower pk_ctlinput (code, xcp) 3545297Ssklower register struct x25config *xcp; 3641591Ssklower { 3741591Ssklower 3845297Ssklower register struct pkcb *pkp; 3945297Ssklower 4045297Ssklower for (pkp = pkcbhead; pkp; pkp = pkp -> pk_next) 4145297Ssklower if (pkp -> pk_xcp == xcp) 4245297Ssklower break; 4345297Ssklower 4442277Ssklower if (pkp == 0) 4541591Ssklower return (EINVAL); 4645297Ssklower 4741591Ssklower switch (code) { 4841591Ssklower case PRC_LINKUP: 4941591Ssklower if (pkp -> pk_state == DTE_WAITING) 5041591Ssklower pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION); 5141591Ssklower break; 5241591Ssklower 5341591Ssklower case PRC_LINKDOWN: 5441591Ssklower pk_restart (pkp, -1); /* Clear all active circuits */ 5541591Ssklower pkp -> pk_state = DTE_WAITING; 5641591Ssklower break; 5741591Ssklower 5841591Ssklower case PRC_LINKRESET: 5941591Ssklower pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION); 6041591Ssklower break; 6141591Ssklower 6241591Ssklower } 6341591Ssklower return (0); 6441591Ssklower } 6545297Ssklower struct ifqueue pkintrq; 6645297Ssklower /* 6745297Ssklower * This routine is called if there are semi-smart devices that do HDLC 6845297Ssklower * in hardware and want to queue the packet and call level 3 directly 6945297Ssklower */ 7045297Ssklower pkintr () 7145297Ssklower { 7245297Ssklower register struct mbuf *m; 7345297Ssklower register struct ifaddr *ifa; 7445297Ssklower register struct ifnet *ifp; 7545297Ssklower register int s; 7641591Ssklower 7745297Ssklower for (;;) { 7845297Ssklower s = splimp (); 7945297Ssklower IF_DEQUEUE (&pkintrq, m); 8045297Ssklower splx (s); 8145297Ssklower if (m == 0) 8245297Ssklower break; 8345297Ssklower if (m->m_len < PKHEADERLN) { 8445297Ssklower printf ("pkintr: packet too short (len=%d)\n", 8545297Ssklower m->m_len); 8645297Ssklower m_freem (m); 8745297Ssklower continue; 8845297Ssklower } 8945297Ssklower if ((m->m_flags & M_PKTHDR) == 0) 9045297Ssklower panic("pkintr"); 9145297Ssklower ifp = m->m_pkthdr.rcvif; 9245297Ssklower /* 9345297Ssklower * look up the appropriate control block 9445297Ssklower */ 9545297Ssklower for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) 9645297Ssklower if (ifa->ifa_addr->sa_family == AF_CCITT) 9745297Ssklower break; 9845297Ssklower if (ifa == 0) 9945297Ssklower continue; 10045297Ssklower pk_input(m, ((struct x25_ifaddr *)ifa)->ia_xcp); 10145297Ssklower } 10245297Ssklower } 10345297Ssklower struct mbuf *pk_bad_packet; 10441591Ssklower /* 10541591Ssklower * X.25 PACKET INPUT 10641591Ssklower * 10741591Ssklower * This procedure is called by a link level procedure whenever 10841591Ssklower * an information frame is received. It decodes the packet and 10941591Ssklower * demultiplexes based on the logical channel number. 11041591Ssklower * 11141591Ssklower */ 11241591Ssklower 11341591Ssklower pk_input (m, xcp) 11441591Ssklower register struct mbuf *m; 11541591Ssklower struct x25config *xcp; 11641591Ssklower { 11741591Ssklower register struct x25_packet *xp; 11841591Ssklower register struct pklcd *lcp; 11941591Ssklower register struct socket *so = 0; 12041591Ssklower register struct pkcb *pkp; 12141591Ssklower int ptype, lcn, lcdstate = LISTEN; 12241591Ssklower static struct x25config *lastxcp; 12341591Ssklower static struct pkcb *lastpkp; 12441591Ssklower 12541591Ssklower if (xcp == lastxcp) 12641591Ssklower pkp = lastpkp; 12741591Ssklower else { 12841591Ssklower for (pkp = pkcbhead; ; pkp = pkp -> pk_next) { 12941591Ssklower if (pkp == 0) { 13041591Ssklower pk_message (0, xcp, "pk_input: unknown network"); 13141591Ssklower m_freem (m); 13241591Ssklower return; 13341591Ssklower } 13441591Ssklower if (pkp -> pk_xcp == xcp) 13541591Ssklower break; 13641591Ssklower } 13741591Ssklower lastxcp = xcp; 13841591Ssklower lastpkp = pkp; 13941591Ssklower } 14041591Ssklower 14141591Ssklower xp = mtod (m, struct x25_packet *); 14241591Ssklower ptype = pk_decode (xp); 14345573Ssklower lcn = LCN(xp); 14441591Ssklower lcp = pkp -> pk_chan[lcn]; 14541591Ssklower 14641591Ssklower /* 14741591Ssklower * If the DTE is in Restart state, then it will ignore data, 14841591Ssklower * interrupt, call setup and clearing, flow control and reset 14941591Ssklower * packets. 15041591Ssklower */ 15141591Ssklower if (lcn < 0 || lcn > pkp -> pk_maxlcn) { 15241591Ssklower pk_message (lcn, pkp -> pk_xcp, "illegal lcn"); 15341591Ssklower m_freem (m); 15441591Ssklower return; 15541591Ssklower } 15641591Ssklower 157*45895Ssklower pk_trace (pkp -> pk_xcp, m, "P-In"); 15841591Ssklower 15941591Ssklower if (pkp -> pk_state != DTE_READY && ptype != RESTART && ptype != RESTART_CONF) { 16041591Ssklower m_freem (m); 16141591Ssklower return; 16241591Ssklower } 16341591Ssklower if (lcp) { 16441591Ssklower so = lcp -> lcd_so; 16541591Ssklower lcdstate = lcp -> lcd_state; 16641591Ssklower } else { 16741591Ssklower if (ptype == CLEAR) { /* idle line probe (Datapac specific) */ 16841591Ssklower /* send response on lcd 0's output queue */ 16941591Ssklower lcp -> lcd_template = pk_template (lcn, X25_CLEAR_CONFIRM); 17041591Ssklower pk_output (lcp); 17141591Ssklower m_freem (m); 17241591Ssklower return; 17341591Ssklower } 17441591Ssklower if (ptype != CALL) 17541591Ssklower ptype = INVALID_PACKET; 17641591Ssklower } 17741591Ssklower 17841591Ssklower if (lcn == 0 && ptype != RESTART && ptype != RESTART_CONF) { 17945297Ssklower pk_message (0, pkp -> pk_xcp, "illegal ptype (%d, %s) on lcn 0", 18045297Ssklower ptype, pk_name[ptype / MAXSTATES]); 18145297Ssklower if (pk_bad_packet) 18245297Ssklower m_freem (pk_bad_packet); 18345297Ssklower pk_bad_packet = m; 18441591Ssklower return; 18541591Ssklower } 18641591Ssklower 18741591Ssklower switch (ptype + lcdstate) { 18841591Ssklower /* 18941591Ssklower * Incoming Call packet received. 19041591Ssklower */ 19141591Ssklower case CALL + LISTEN: 192*45895Ssklower incoming_call (pkp, m); 19341591Ssklower break; 19441591Ssklower 19541591Ssklower /* 19641591Ssklower * Call collision: Just throw this "incoming call" away since 19741591Ssklower * the DCE will ignore it anyway. 19841591Ssklower */ 19941591Ssklower case CALL + SENT_CALL: 20045573Ssklower pk_message ((int)lcn, pkp -> pk_xcp, 20141591Ssklower "incoming call collision"); 20241591Ssklower break; 20341591Ssklower 20441591Ssklower /* 20541591Ssklower * Call confirmation packet received. This usually means our 20641591Ssklower * previous connect request is now complete. 20741591Ssklower */ 20841591Ssklower case CALL_ACCEPTED + SENT_CALL: 20941591Ssklower call_accepted (lcp, xp, m -> m_len); 21041591Ssklower break; 21141591Ssklower 21241591Ssklower /* 21341591Ssklower * This condition can only happen if the previous state was 21441591Ssklower * SENT_CALL. Just ignore the packet, eventually a clear 21541591Ssklower * confirmation should arrive. 21641591Ssklower */ 21741591Ssklower case CALL_ACCEPTED + SENT_CLEAR: 21841591Ssklower break; 21941591Ssklower 22041591Ssklower /* 22141591Ssklower * Clear packet received. This requires a complete tear down 22241591Ssklower * of the virtual circuit. Free buffers and control blocks. 22341591Ssklower * and send a clear confirmation. 22441591Ssklower */ 22541591Ssklower case CLEAR + READY: 22641591Ssklower case CLEAR + RECEIVED_CALL: 22741591Ssklower case CLEAR + SENT_CALL: 22841591Ssklower case CLEAR + DATA_TRANSFER: 22941591Ssklower lcp -> lcd_state = RECEIVED_CLEAR; 23041591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CLEAR_CONFIRM); 23141591Ssklower pk_output (lcp); 23241591Ssklower pk_clearcause (pkp, xp); 23341591Ssklower pk_close (lcp); 23441591Ssklower break; 23541591Ssklower 23641591Ssklower /* 23741591Ssklower * Clear collision: Treat this clear packet as a confirmation. 23841591Ssklower */ 23941591Ssklower case CLEAR + SENT_CLEAR: 24041591Ssklower pk_close (lcp); 24141591Ssklower break; 24241591Ssklower 24341591Ssklower /* 24441591Ssklower * Clear confirmation received. This usually means the virtual 24541591Ssklower * circuit is now completely removed. 24641591Ssklower */ 24741591Ssklower case CLEAR_CONF + SENT_CLEAR: 24841591Ssklower pk_close (lcp); 24941591Ssklower break; 25041591Ssklower 25141591Ssklower /* 25241591Ssklower * A clear confirmation on an unassigned logical channel - just 25341591Ssklower * ignore it. Note: All other packets on an unassigned channel 25441591Ssklower * results in a clear. 25541591Ssklower */ 25641591Ssklower case CLEAR_CONF + READY: 25741591Ssklower break; 25841591Ssklower 25941591Ssklower /* 26041591Ssklower * Data packet received. Pass on to next level. Move the Q and M 26141591Ssklower * bits into the data portion for the next level. 26241591Ssklower */ 26341591Ssklower case DATA + DATA_TRANSFER: 26441591Ssklower if (lcp -> lcd_reset_condition) { 26541591Ssklower ptype = DELETE_PACKET; 26641591Ssklower break; 26741591Ssklower } 26841591Ssklower 26941591Ssklower /* 27041591Ssklower * Process the P(S) flow control information in this Data packet. 27141591Ssklower * Check that the packets arrive in the correct sequence and that 27241591Ssklower * they are within the "lcd_input_window". Input window rotation is 27341591Ssklower * initiated by the receive interface. 27441591Ssklower */ 27541591Ssklower 27641591Ssklower if (PS(xp) != ((lcp -> lcd_rsn + 1) % MODULUS) || 27741591Ssklower PS(xp) == ((lcp -> lcd_input_window + lcp->lcd_windowsize) % MODULUS)) { 27841591Ssklower m_freem (m); 279*45895Ssklower pk_procerror (RESET, lcp, "p(s) flow control error", 1); 28041591Ssklower break; 28141591Ssklower } 28241591Ssklower lcp -> lcd_rsn = PS(xp); 28341591Ssklower 28441591Ssklower if (pk_ack (lcp, PR(xp)) != PACKET_OK) { 28541591Ssklower m_freem (m); 28641591Ssklower break; 28741591Ssklower } 288*45895Ssklower m -> m_data += PKHEADERLN; 289*45895Ssklower m -> m_len -= PKHEADERLN; 290*45895Ssklower m -> m_pkthdr.len -= PKHEADERLN; 291*45895Ssklower 292*45895Ssklower if (lcp -> lcd_flags & X25_MBS_HOLD) { 293*45895Ssklower register struct mbuf *n = lcp -> lcd_cps; 294*45895Ssklower int mbit = MBIT(xp); 295*45895Ssklower octet q_and_d_bits; 296*45895Ssklower 297*45895Ssklower if (n) { 298*45895Ssklower n -> m_pkthdr.len += m -> m_pkthdr.len; 299*45895Ssklower while (n -> m_next) 300*45895Ssklower n = n -> m_next; 301*45895Ssklower n -> m_next = m; 302*45895Ssklower m = lcp -> lcd_cps; 303*45895Ssklower 304*45895Ssklower if (lcp -> lcd_cpsmax && 305*45895Ssklower n -> m_pkthdr.len > lcp -> lcd_cpsmax) { 306*45895Ssklower pk_procerror (RESET, lcp, 307*45895Ssklower "C.P.S. overflow", 128); 308*45895Ssklower return; 309*45895Ssklower } 310*45895Ssklower q_and_d_bits = 0xc0 & *(octet *)xp; 311*45895Ssklower xp = (struct x25_packet *) 312*45895Ssklower (mtod(m, octet *) - PKHEADERLN); 313*45895Ssklower *(octet *)xp |= q_and_d_bits; 314*45895Ssklower } 315*45895Ssklower if (mbit) { 316*45895Ssklower lcp -> lcd_cps = m; 317*45895Ssklower return; 318*45895Ssklower } 319*45895Ssklower lcp -> lcd_cps = 0; 320*45895Ssklower } 32145297Ssklower if (so == 0) 32245297Ssklower break; 32341591Ssklower if (lcp -> lcd_flags & X25_MQBIT) { 32445573Ssklower octet t = (xp -> q_bit) ? t = 0x80 : 0; 32541591Ssklower 32645573Ssklower if (MBIT(xp)) 32745573Ssklower t |= 0x40; 32843361Ssklower m -> m_data -= 1; 32941591Ssklower m -> m_len += 1; 330*45895Ssklower m -> m_pkthdr.len += 1; 33145573Ssklower *mtod(m, octet *) = t; 33241591Ssklower } 33341591Ssklower 33441591Ssklower /* 33541591Ssklower * Discard Q-BIT packets if the application 33641591Ssklower * doesn't want to be informed of M and Q bit status 33741591Ssklower */ 33841591Ssklower if (xp -> q_bit && (lcp -> lcd_flags & X25_MQBIT) == 0) { 33941591Ssklower m_freem (m); 34041591Ssklower lcp -> lcd_rxcnt++; 34141591Ssklower /* 34241591Ssklower * NB. This is dangerous: sending a RR here can 34341591Ssklower * cause sequence number errors if a previous data 34441591Ssklower * packet has not yet been passed up to the application 34541591Ssklower * (RR's are normally generated via PRU_RCVD). 34641591Ssklower */ 34741591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RR); 34841591Ssklower pk_output (lcp); 34941591Ssklower } else { 35041591Ssklower sbappendrecord (&so -> so_rcv, m); 35141591Ssklower sorwakeup (so); 35241591Ssklower } 35341591Ssklower break; 35441591Ssklower 35541591Ssklower /* 35641591Ssklower * Interrupt packet received. 35741591Ssklower */ 35841591Ssklower case INTERRUPT + DATA_TRANSFER: 35941591Ssklower if (lcp -> lcd_reset_condition) 36041591Ssklower break; 36141591Ssklower lcp -> lcd_intrdata = xp -> packet_data; 36241591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM); 36341591Ssklower pk_output (lcp); 364*45895Ssklower m -> m_data += PKHEADERLN; 365*45895Ssklower m -> m_len -= PKHEADERLN; 366*45895Ssklower m -> m_pkthdr.len -= PKHEADERLN; 36745297Ssklower MCHTYPE(m, MT_OOBDATA); 368*45895Ssklower if (so) { 369*45895Ssklower if (so -> so_options & SO_OOBINLINE) 370*45895Ssklower sbinsertoob (&so -> so_rcv, m); 371*45895Ssklower else 372*45895Ssklower m_freem (m); 37345297Ssklower sohasoutofband (so); 374*45895Ssklower } 37541591Ssklower break; 37641591Ssklower 37741591Ssklower /* 37841591Ssklower * Interrupt confirmation packet received. 37941591Ssklower */ 38041591Ssklower case INTERRUPT_CONF + DATA_TRANSFER: 38141591Ssklower if (lcp -> lcd_reset_condition) 38241591Ssklower break; 38341591Ssklower if (lcp -> lcd_intrconf_pending == TRUE) 38441591Ssklower lcp -> lcd_intrconf_pending = FALSE; 38541591Ssklower else 386*45895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 43); 38741591Ssklower break; 38841591Ssklower 38941591Ssklower /* 39041591Ssklower * Receiver ready received. Rotate the output window and output 39141591Ssklower * any data packets waiting transmission. 39241591Ssklower */ 39341591Ssklower case RR + DATA_TRANSFER: 39445297Ssklower if (lcp -> lcd_reset_condition || 39545297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 39645297Ssklower ptype = DELETE_PACKET; 39741591Ssklower break; 39845297Ssklower } 39941591Ssklower if (lcp -> lcd_rnr_condition == TRUE) 40041591Ssklower lcp -> lcd_rnr_condition = FALSE; 40141591Ssklower pk_output (lcp); 40241591Ssklower break; 40341591Ssklower 40441591Ssklower /* 40541591Ssklower * Receiver Not Ready received. Packets up to the P(R) can be 40641591Ssklower * be sent. Condition is cleared with a RR. 40741591Ssklower */ 40841591Ssklower case RNR + DATA_TRANSFER: 40945297Ssklower if (lcp -> lcd_reset_condition || 41045297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 41145297Ssklower ptype = DELETE_PACKET; 41241591Ssklower break; 41345297Ssklower } 41441591Ssklower lcp -> lcd_rnr_condition = TRUE; 41541591Ssklower break; 41641591Ssklower 41741591Ssklower /* 41841591Ssklower * Reset packet received. Set state to FLOW_OPEN. The Input and 41941591Ssklower * Output window edges ar set to zero. Both the send and receive 42041591Ssklower * numbers are reset. A confirmation is returned. 42141591Ssklower */ 42241591Ssklower case RESET + DATA_TRANSFER: 42341591Ssklower if (lcp -> lcd_reset_condition) 42441591Ssklower /* Reset collision. Just ignore packet. */ 42541591Ssklower break; 42641591Ssklower 42741591Ssklower pk_resetcause (pkp, xp); 42841591Ssklower lcp -> lcd_window_condition = lcp -> lcd_rnr_condition = 42941591Ssklower lcp -> lcd_intrconf_pending = FALSE; 43041591Ssklower lcp -> lcd_output_window = lcp -> lcd_input_window = 43141591Ssklower lcp -> lcd_last_transmitted_pr = 0; 43241591Ssklower lcp -> lcd_ssn = 0; 43341591Ssklower lcp -> lcd_rsn = MODULUS - 1; 43441591Ssklower 43541591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM); 43641591Ssklower pk_output (lcp); 43745297Ssklower 438*45895Ssklower pk_flush(lcp); 43945297Ssklower if (so == 0) 44045297Ssklower break; 44145297Ssklower wakeup ((caddr_t) & so -> so_timeo); 44245297Ssklower sorwakeup (so); 44345297Ssklower sowwakeup (so); 44441591Ssklower break; 44541591Ssklower 44641591Ssklower /* 44741591Ssklower * Reset confirmation received. 44841591Ssklower */ 44941591Ssklower case RESET_CONF + DATA_TRANSFER: 45041591Ssklower if (lcp -> lcd_reset_condition) { 45141591Ssklower lcp -> lcd_reset_condition = FALSE; 45241591Ssklower pk_output (lcp); 45341591Ssklower } 45441591Ssklower else 455*45895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 32); 45641591Ssklower break; 45741591Ssklower 45841591Ssklower case DATA + SENT_CLEAR: 45941591Ssklower ptype = DELETE_PACKET; 46041591Ssklower case RR + SENT_CLEAR: 46141591Ssklower case RNR + SENT_CLEAR: 46241591Ssklower case INTERRUPT + SENT_CLEAR: 46341591Ssklower case INTERRUPT_CONF + SENT_CLEAR: 46441591Ssklower case RESET + SENT_CLEAR: 46541591Ssklower case RESET_CONF + SENT_CLEAR: 46645297Ssklower /* Just ignore p if we have sent a CLEAR already. 46741591Ssklower */ 46841591Ssklower break; 46941591Ssklower 47041591Ssklower /* 47141591Ssklower * Restart sets all the permanent virtual circuits to the "Data 47241591Ssklower * Transfer" stae and all the switched virtual circuits to the 47341591Ssklower * "Ready" state. 47441591Ssklower */ 47541591Ssklower case RESTART + READY: 47641591Ssklower switch (pkp -> pk_state) { 47741591Ssklower case DTE_SENT_RESTART: 47841591Ssklower /* Restart collision. */ 47941591Ssklower pkp -> pk_state = DTE_READY; 48041591Ssklower pk_message (0, pkp -> pk_xcp, 48141591Ssklower "Packet level operational"); 48241591Ssklower break; 48341591Ssklower 48441591Ssklower default: 48541591Ssklower pk_restart (pkp, -1); 48641591Ssklower pk_restartcause (pkp, xp); 48741591Ssklower pkp -> pk_chan[0] -> lcd_template = pk_template (0, 48841591Ssklower X25_RESTART_CONFIRM); 48941591Ssklower pk_output (pkp -> pk_chan[0]); 49041591Ssklower } 49141591Ssklower break; 49241591Ssklower 49341591Ssklower /* 49441591Ssklower * Restart confirmation received. All logical channels are set 49541591Ssklower * to READY. 49641591Ssklower */ 49741591Ssklower case RESTART_CONF + READY: 49841591Ssklower switch (pkp -> pk_state) { 49941591Ssklower case DTE_SENT_RESTART: 50041591Ssklower pkp -> pk_state = DTE_READY; 50141591Ssklower pk_message (0, pkp -> pk_xcp, 50241591Ssklower "Packet level operational"); 50341591Ssklower break; 50441591Ssklower 50541591Ssklower default: 50641591Ssklower /* Restart local procedure error. */ 50741591Ssklower pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR); 50841591Ssklower pkp -> pk_state = DTE_SENT_RESTART; 50941591Ssklower } 51041591Ssklower break; 51141591Ssklower 51241591Ssklower default: 51341591Ssklower if (lcp) { 514*45895Ssklower pk_procerror (CLEAR, lcp, "unknown packet error", 33); 51541591Ssklower pk_message (lcn, pkp -> pk_xcp, 51641591Ssklower "\"%s\" unexpected in \"%s\" state", 51741591Ssklower pk_name[ptype/MAXSTATES], pk_state[lcdstate]); 518*45895Ssklower } else 51945573Ssklower pk_message (lcn, pkp -> pk_xcp, 52041591Ssklower "packet arrived on unassigned lcn"); 52141591Ssklower break; 52241591Ssklower } 523*45895Ssklower if (so == 0 && lcp -> lcd_upper && 524*45895Ssklower (lcdstate == SENT_CALL || lcdstate == DATA_TRANSFER)) { 525*45895Ssklower if (ptype != DATA && ptype != INTERRUPT) 526*45895Ssklower MCHTYPE(m, MT_CONTROL); 52745297Ssklower lcp -> lcd_upper (lcp, m); 528*45895Ssklower } else if (ptype != DATA && ptype != INTERRUPT) 52941591Ssklower m_freem (m); 53041591Ssklower } 53141591Ssklower 53241591Ssklower 53341591Ssklower /* 53441591Ssklower * This routine handles incoming call packets. It matches the protocol 53541591Ssklower * field on the Call User Data field (usually the first four bytes) with 53641591Ssklower * sockets awaiting connections. 53741591Ssklower */ 53841591Ssklower 53941591Ssklower static 540*45895Ssklower incoming_call (pkp, m0) 541*45895Ssklower struct mbuf *m0; 54241591Ssklower struct pkcb *pkp; 54341591Ssklower { 54442277Ssklower register struct pklcd *lcp = 0, *l; 54541591Ssklower register struct sockaddr_x25 *sa; 54641591Ssklower register struct x25_calladdr *a; 54742277Ssklower register struct socket *so = 0; 548*45895Ssklower struct x25_packet *xp = mtod(m0, struct x25_packet *); 54941591Ssklower struct mbuf *m; 550*45895Ssklower int len = m0->m_pkthdr.len; 55141591Ssklower register int l1, l2; 55241591Ssklower char *e, *errstr = "server unavailable"; 553*45895Ssklower octet *u, *facp; 55445573Ssklower int lcn = LCN(xp); 55541591Ssklower 55641591Ssklower /* First, copy the data from the incoming call packet to a X25_socket 55741591Ssklower descriptor. */ 55841591Ssklower 55941591Ssklower a = (struct x25_calladdr *) &xp -> packet_data; 56041591Ssklower l1 = a -> calling_addrlen; 56141591Ssklower l2 = a -> called_addrlen; 56245297Ssklower if ((m = m_getclr (M_DONTWAIT, MT_SONAME)) == 0) 56341591Ssklower return; 56441591Ssklower sa = mtod (m, struct sockaddr_x25 *); 56541591Ssklower u = (octet *) (a -> address_field + l2 / 2); 56641591Ssklower e = sa -> x25_addr; 56741591Ssklower if (l2 & 0x01) { 56841591Ssklower *e++ = *u++ & 0x0f; 56941591Ssklower l1--; 57041591Ssklower } 57141591Ssklower from_bcd (e, &u, l1); 57241591Ssklower if (l1 & 0x01) 57341591Ssklower u++; 57441591Ssklower 575*45895Ssklower facp = u; 57641591Ssklower parse_facilities (u, sa); 57741591Ssklower u += *u + 1; 57841591Ssklower sa -> x25_udlen = min (16, ((octet *)xp) + len - u); 57941591Ssklower if (sa -> x25_udlen < 0) 58041591Ssklower sa -> x25_udlen = 0; 58141591Ssklower bcopy ((caddr_t)u, sa -> x25_udata, (unsigned)sa -> x25_udlen); 58241591Ssklower 58341591Ssklower /* 58441591Ssklower * Now, loop through the listen sockets looking for a match on the 58541591Ssklower * PID. That is the first four octets of the user data field. This 58641591Ssklower * is the closest thing to a port number for X.25 packets. What it 58741591Ssklower * does provide is away of multiplexing services at the user level. 58841591Ssklower */ 58941591Ssklower 59041591Ssklower for (l = pk_listenhead; l; l = l -> lcd_listen) { 59141591Ssklower struct sockaddr_x25 *sxp = l -> lcd_ceaddr; 59241591Ssklower 59341591Ssklower if (bcmp (sxp -> x25_udata, sa -> x25_udata, sxp->x25_udlen)) 59441591Ssklower continue; 59545165Ssklower if (sxp -> x25_net && 59645165Ssklower sxp -> x25_net != pkp->pk_xc.xc_addr.x25_net) 59741591Ssklower continue; 59841591Ssklower /* 59941591Ssklower * don't accept incoming collect calls unless 60041591Ssklower * the server sets the reverse charging option. 60141591Ssklower */ 60241591Ssklower if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 && 60341591Ssklower sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) { 60441591Ssklower errstr = "incoming collect call refused"; 60541591Ssklower break; 60641591Ssklower } 60745573Ssklower /* 60845573Ssklower * don't accept incoming calls with the D-Bit on 60945573Ssklower * unless the server agrees 61045573Ssklower */ 61145573Ssklower if (xp -> d_bit && !(sxp -> x25_opts.op_flags & X25_DBIT)) { 61245573Ssklower errstr = "incoming D-Bit mismatch"; 61345573Ssklower break; 61445573Ssklower } 61542277Ssklower if (l -> lcd_so) { 61645165Ssklower if (so = sonewconn (l -> lcd_so, SS_ISCONNECTED)) 61742277Ssklower lcp = (struct pklcd *) so -> so_pcb; 61842277Ssklower } else 61942277Ssklower lcp = pk_attach((struct socket *) 0); 62042277Ssklower if (lcp == 0) { 62141591Ssklower /* 62241591Ssklower * Insufficient space or too many unaccepted 62341591Ssklower * connections. Just throw the call away. 62441591Ssklower */ 62541591Ssklower errstr = "server malfunction"; 62641591Ssklower break; 62741591Ssklower } 62843361Ssklower lcp -> lcd_upper = l -> lcd_upper; 62943361Ssklower lcp -> lcd_upnext = l -> lcd_upnext; 63041591Ssklower lcp -> lcd_lcn = lcn; 63141591Ssklower lcp -> lcd_state = RECEIVED_CALL; 63241591Ssklower lcp -> lcd_craddr = sa; 63341591Ssklower sa -> x25_opts.op_flags |= sxp -> x25_opts.op_flags & 63441591Ssklower ~X25_REVERSE_CHARGE; 63541591Ssklower pk_assoc (pkp, lcp, sa); 63641591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED); 63745573Ssklower if (lcp -> lcd_flags & X25_DBIT) { 63845573Ssklower if (xp -> d_bit) 639*45895Ssklower mtod(lcp -> lcd_template, 640*45895Ssklower struct x25_packet *) -> d_bit = 1; 64145573Ssklower else 64245573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 64345573Ssklower } 64443361Ssklower if (so) { 64543361Ssklower pk_output (lcp); 64642277Ssklower soisconnected (so); 647*45895Ssklower if (so -> so_options & SO_OOBINLINE) 648*45895Ssklower save_extra(m0, facp, so); 649*45895Ssklower } else if (lcp -> lcd_upper) { 650*45895Ssklower m -> m_next = m0; 651*45895Ssklower (*lcp -> lcd_upper) (lcp, m); 652*45895Ssklower (void) m_free (m); /* only m; m0 freed by caller */ 653*45895Ssklower } 65441591Ssklower return; 65541591Ssklower } 65641591Ssklower 65741591Ssklower /* 65841591Ssklower * If the call fails for whatever reason, we still need to build a 65941591Ssklower * skeleton LCD in order to be able to properly receive the CLEAR 66041591Ssklower * CONFIRMATION. 66141591Ssklower */ 66241591Ssklower #ifdef WATERLOO /* be explicit */ 66341591Ssklower if (l == 0 && bcmp(sa->x25_udata, "ean", 3) == 0) 66441591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s", 66541591Ssklower sa->x25_addr, sa->x25_udata[3] & 0xff, errstr); 66641591Ssklower else if (l == 0 && bcmp(sa->x25_udata, "\1\0\0\0", 4) == 0) 66741591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s", 66841591Ssklower sa->x25_addr, errstr); 66941591Ssklower else 67041591Ssklower #endif 67141591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s", 67241591Ssklower sa -> x25_addr, sa -> x25_udata[0] & 0xff, 67341591Ssklower sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff, 67441591Ssklower sa -> x25_udata[3] & 0xff, errstr); 67545297Ssklower if ((lcp = pk_attach((struct socket *)0)) == 0) { 67645297Ssklower (void) m_free (m); 67741591Ssklower return; 67841591Ssklower } 67941591Ssklower lcp -> lcd_lcn = lcn; 68041591Ssklower lcp -> lcd_state = RECEIVED_CALL; 68141591Ssklower pk_assoc (pkp, lcp, sa); 68245297Ssklower (void) m_free (m); 683*45895Ssklower pk_clear (lcp, 0, 1); 68441591Ssklower } 68541591Ssklower 68641591Ssklower static 687*45895Ssklower save_extra(m0, fp, so) 688*45895Ssklower struct mbuf *m0; 689*45895Ssklower octet *fp; 690*45895Ssklower struct socket *so; 691*45895Ssklower { 692*45895Ssklower register struct mbuf *m; 693*45895Ssklower struct cmsghdr cmsghdr; 694*45895Ssklower if (m = m_copym (m, 0, (int)M_COPYALL)) { 695*45895Ssklower int off = fp - mtod (m0, octet *); 696*45895Ssklower int len = m->m_pkthdr.len - off + sizeof (cmsghdr); 697*45895Ssklower cmsghdr.cmsg_len = len; 698*45895Ssklower cmsghdr.cmsg_level = AF_CCITT; 699*45895Ssklower cmsghdr.cmsg_type = PK_FACILITIES; 700*45895Ssklower m_adj (m, off); 701*45895Ssklower M_PREPEND (m, sizeof(cmsghdr), M_DONTWAIT); 702*45895Ssklower if (m == 0) 703*45895Ssklower return; 704*45895Ssklower bcopy ((caddr_t)&cmsghdr, mtod (m, caddr_t), sizeof (cmsghdr)); 705*45895Ssklower MCHTYPE(m, MT_CONTROL); 706*45895Ssklower sbappendrecord(&so -> so_rcv, m); 707*45895Ssklower } 708*45895Ssklower } 709*45895Ssklower 710*45895Ssklower static 71141591Ssklower call_accepted (lcp, xp, len) 71241591Ssklower struct pklcd *lcp; 71341591Ssklower struct x25_packet *xp; 71441591Ssklower { 71541591Ssklower register struct x25_calladdr *ap; 71641591Ssklower register octet *fcp; 71741591Ssklower 71841591Ssklower lcp -> lcd_state = DATA_TRANSFER; 71945297Ssklower if (lcp -> lcd_so) 72045297Ssklower soisconnected (lcp -> lcd_so); 72145573Ssklower if ((lcp -> lcd_flags & X25_DBIT) && (xp -> d_bit == 0)) 72245573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 72341591Ssklower if (len > 3) { 72441591Ssklower ap = (struct x25_calladdr *) &xp -> packet_data; 72541591Ssklower fcp = (octet *) ap -> address_field + (ap -> calling_addrlen + 72641591Ssklower ap -> called_addrlen + 1) / 2; 72741591Ssklower if (fcp + *fcp <= ((octet *)xp) + len) 72841591Ssklower parse_facilities (fcp, lcp -> lcd_ceaddr); 72941591Ssklower } 73041591Ssklower pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr); 73141591Ssklower } 73241591Ssklower 73341591Ssklower static 73441591Ssklower parse_facilities (fcp, sa) 73541591Ssklower register octet *fcp; 73641591Ssklower register struct sockaddr_x25 *sa; 73741591Ssklower { 73841591Ssklower register octet *maxfcp; 73941591Ssklower 74041591Ssklower maxfcp = fcp + *fcp; 74141591Ssklower fcp++; 74241591Ssklower while (fcp < maxfcp) { 74341591Ssklower /* 74441591Ssklower * Ignore national DCE or DTE facilities 74541591Ssklower */ 74641591Ssklower if (*fcp == 0 || *fcp == 0xff) 74741591Ssklower break; 74841591Ssklower switch (*fcp) { 74941591Ssklower case FACILITIES_WINDOWSIZE: 75041591Ssklower sa -> x25_opts.op_wsize = fcp[1]; 75141591Ssklower fcp += 3; 75241591Ssklower break; 75341591Ssklower 75441591Ssklower case FACILITIES_PACKETSIZE: 75541591Ssklower sa -> x25_opts.op_psize = fcp[1]; 75641591Ssklower fcp += 3; 75741591Ssklower break; 75841591Ssklower 75941591Ssklower case FACILITIES_THROUGHPUT: 76041591Ssklower sa -> x25_opts.op_speed = fcp[1]; 76141591Ssklower fcp += 2; 76241591Ssklower break; 76341591Ssklower 76441591Ssklower case FACILITIES_REVERSE_CHARGE: 76541591Ssklower if (fcp[1] & 01) 76641591Ssklower sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE; 76741591Ssklower /* 76841591Ssklower * Datapac specific: for a X.25(1976) DTE, bit 2 76941591Ssklower * indicates a "hi priority" (eg. international) call. 77041591Ssklower */ 77141591Ssklower if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0) 77241591Ssklower sa -> x25_opts.op_psize = X25_PS128; 77341591Ssklower fcp += 2; 77441591Ssklower break; 77541591Ssklower 77641591Ssklower default: 77741591Ssklower /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/ 77841591Ssklower switch ((*fcp & 0xc0) >> 6) { 77941591Ssklower case 0: /* class A */ 78041591Ssklower fcp += 2; 78141591Ssklower break; 78241591Ssklower 78341591Ssklower case 1: 78441591Ssklower fcp += 3; 78541591Ssklower break; 78641591Ssklower 78741591Ssklower case 2: 78841591Ssklower fcp += 4; 78941591Ssklower break; 79041591Ssklower 79141591Ssklower case 3: 79241591Ssklower fcp++; 79341591Ssklower fcp += *fcp; 79441591Ssklower } 79541591Ssklower } 79641591Ssklower } 79741591Ssklower } 79841591Ssklower 79941591Ssklower from_bcd (a, x, len) 80041591Ssklower register char *a; 80141591Ssklower register octet **x; 80241591Ssklower register int len; 80341591Ssklower { 80441591Ssklower register int posn = 0; 80541591Ssklower 80641591Ssklower while (--len >= 0) { 80741591Ssklower if (posn++ & 0x01) 80841591Ssklower *a = *(*x)++ & 0x0f; 80941591Ssklower else 81041591Ssklower *a = (**x >> 4) & 0x0F; 81141591Ssklower *a++ |= 0x30; 81241591Ssklower } 81341591Ssklower } 814