141709Ssklower /* 241709Ssklower * Copyright (c) University of British Columbia, 1984 349252Ssklower * Copyright (c) 1991 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*49593Ssklower * @(#)pk_input.c 7.11 (Berkeley) 05/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; 104*49593Ssklower struct mbuf_cache pk_input_cache = {0 }; 10541591Ssklower /* 10641591Ssklower * X.25 PACKET INPUT 10741591Ssklower * 10841591Ssklower * This procedure is called by a link level procedure whenever 10941591Ssklower * an information frame is received. It decodes the packet and 11041591Ssklower * demultiplexes based on the logical channel number. 11141591Ssklower * 11241591Ssklower */ 11341591Ssklower 11441591Ssklower pk_input (m, xcp) 11541591Ssklower register struct mbuf *m; 11641591Ssklower struct x25config *xcp; 11741591Ssklower { 11841591Ssklower register struct x25_packet *xp; 11941591Ssklower register struct pklcd *lcp; 12041591Ssklower register struct socket *so = 0; 12141591Ssklower register struct pkcb *pkp; 12241591Ssklower int ptype, lcn, lcdstate = LISTEN; 12341591Ssklower static struct x25config *lastxcp; 12441591Ssklower static struct pkcb *lastpkp; 12541591Ssklower 126*49593Ssklower if (pk_input_cache.mbc_size || pk_input_cache.mbc_oldsize) 127*49593Ssklower mbuf_cache(&pk_input_cache, m); 12841591Ssklower if (xcp == lastxcp) 12941591Ssklower pkp = lastpkp; 13041591Ssklower else { 13141591Ssklower for (pkp = pkcbhead; ; pkp = pkp -> pk_next) { 13241591Ssklower if (pkp == 0) { 13341591Ssklower pk_message (0, xcp, "pk_input: unknown network"); 13441591Ssklower m_freem (m); 13541591Ssklower return; 13641591Ssklower } 13741591Ssklower if (pkp -> pk_xcp == xcp) 13841591Ssklower break; 13941591Ssklower } 14041591Ssklower lastxcp = xcp; 14141591Ssklower lastpkp = pkp; 14241591Ssklower } 14341591Ssklower 14441591Ssklower xp = mtod (m, struct x25_packet *); 14541591Ssklower ptype = pk_decode (xp); 14645573Ssklower lcn = LCN(xp); 14741591Ssklower lcp = pkp -> pk_chan[lcn]; 14841591Ssklower 14941591Ssklower /* 15041591Ssklower * If the DTE is in Restart state, then it will ignore data, 15141591Ssklower * interrupt, call setup and clearing, flow control and reset 15241591Ssklower * packets. 15341591Ssklower */ 15441591Ssklower if (lcn < 0 || lcn > pkp -> pk_maxlcn) { 15541591Ssklower pk_message (lcn, pkp -> pk_xcp, "illegal lcn"); 15641591Ssklower m_freem (m); 15741591Ssklower return; 15841591Ssklower } 15941591Ssklower 16045895Ssklower pk_trace (pkp -> pk_xcp, m, "P-In"); 16141591Ssklower 16241591Ssklower if (pkp -> pk_state != DTE_READY && ptype != RESTART && ptype != RESTART_CONF) { 16341591Ssklower m_freem (m); 16441591Ssklower return; 16541591Ssklower } 16641591Ssklower if (lcp) { 16741591Ssklower so = lcp -> lcd_so; 16841591Ssklower lcdstate = lcp -> lcd_state; 16941591Ssklower } else { 17041591Ssklower if (ptype == CLEAR) { /* idle line probe (Datapac specific) */ 17141591Ssklower /* send response on lcd 0's output queue */ 17241591Ssklower lcp -> lcd_template = pk_template (lcn, X25_CLEAR_CONFIRM); 17341591Ssklower pk_output (lcp); 17441591Ssklower m_freem (m); 17541591Ssklower return; 17641591Ssklower } 17741591Ssklower if (ptype != CALL) 17841591Ssklower ptype = INVALID_PACKET; 17941591Ssklower } 18041591Ssklower 18141591Ssklower if (lcn == 0 && ptype != RESTART && ptype != RESTART_CONF) { 18245297Ssklower pk_message (0, pkp -> pk_xcp, "illegal ptype (%d, %s) on lcn 0", 18345297Ssklower ptype, pk_name[ptype / MAXSTATES]); 18445297Ssklower if (pk_bad_packet) 18545297Ssklower m_freem (pk_bad_packet); 18645297Ssklower pk_bad_packet = m; 18741591Ssklower return; 18841591Ssklower } 18941591Ssklower 19041591Ssklower switch (ptype + lcdstate) { 19141591Ssklower /* 19241591Ssklower * Incoming Call packet received. 19341591Ssklower */ 19441591Ssklower case CALL + LISTEN: 195*49593Ssklower pk_incoming_call (pkp, m); 19641591Ssklower break; 19741591Ssklower 19841591Ssklower /* 19941591Ssklower * Call collision: Just throw this "incoming call" away since 20041591Ssklower * the DCE will ignore it anyway. 20141591Ssklower */ 20241591Ssklower case CALL + SENT_CALL: 20345573Ssklower pk_message ((int)lcn, pkp -> pk_xcp, 20441591Ssklower "incoming call collision"); 20541591Ssklower break; 20641591Ssklower 20741591Ssklower /* 20841591Ssklower * Call confirmation packet received. This usually means our 20941591Ssklower * previous connect request is now complete. 21041591Ssklower */ 21141591Ssklower case CALL_ACCEPTED + SENT_CALL: 21249252Ssklower MCHTYPE(m, MT_CONTROL); 213*49593Ssklower pk_call_accepted (lcp, m); 21441591Ssklower break; 21541591Ssklower 21641591Ssklower /* 21741591Ssklower * This condition can only happen if the previous state was 21841591Ssklower * SENT_CALL. Just ignore the packet, eventually a clear 21941591Ssklower * confirmation should arrive. 22041591Ssklower */ 22141591Ssklower case CALL_ACCEPTED + SENT_CLEAR: 22241591Ssklower break; 22341591Ssklower 22441591Ssklower /* 22541591Ssklower * Clear packet received. This requires a complete tear down 22641591Ssklower * of the virtual circuit. Free buffers and control blocks. 22741591Ssklower * and send a clear confirmation. 22841591Ssklower */ 22941591Ssklower case CLEAR + READY: 23041591Ssklower case CLEAR + RECEIVED_CALL: 23141591Ssklower case CLEAR + SENT_CALL: 23241591Ssklower case CLEAR + DATA_TRANSFER: 23341591Ssklower lcp -> lcd_state = RECEIVED_CLEAR; 23441591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CLEAR_CONFIRM); 23541591Ssklower pk_output (lcp); 23641591Ssklower pk_clearcause (pkp, xp); 23749252Ssklower if (lcp -> lcd_upper) { 23849252Ssklower MCHTYPE(m, MT_CONTROL); 23949252Ssklower lcp -> lcd_upper (lcp, m); 24049252Ssklower } 24141591Ssklower pk_close (lcp); 24249252Ssklower lcp = 0; 24341591Ssklower break; 24441591Ssklower 24541591Ssklower /* 24641591Ssklower * Clear collision: Treat this clear packet as a confirmation. 24741591Ssklower */ 24841591Ssklower case CLEAR + SENT_CLEAR: 24941591Ssklower pk_close (lcp); 25041591Ssklower break; 25141591Ssklower 25241591Ssklower /* 25341591Ssklower * Clear confirmation received. This usually means the virtual 25441591Ssklower * circuit is now completely removed. 25541591Ssklower */ 25641591Ssklower case CLEAR_CONF + SENT_CLEAR: 25741591Ssklower pk_close (lcp); 25841591Ssklower break; 25941591Ssklower 26041591Ssklower /* 26141591Ssklower * A clear confirmation on an unassigned logical channel - just 26241591Ssklower * ignore it. Note: All other packets on an unassigned channel 26341591Ssklower * results in a clear. 26441591Ssklower */ 26541591Ssklower case CLEAR_CONF + READY: 26641591Ssklower break; 26741591Ssklower 26841591Ssklower /* 26941591Ssklower * Data packet received. Pass on to next level. Move the Q and M 27041591Ssklower * bits into the data portion for the next level. 27141591Ssklower */ 27241591Ssklower case DATA + DATA_TRANSFER: 27341591Ssklower if (lcp -> lcd_reset_condition) { 27441591Ssklower ptype = DELETE_PACKET; 27541591Ssklower break; 27641591Ssklower } 27741591Ssklower 27841591Ssklower /* 27941591Ssklower * Process the P(S) flow control information in this Data packet. 28041591Ssklower * Check that the packets arrive in the correct sequence and that 28141591Ssklower * they are within the "lcd_input_window". Input window rotation is 28241591Ssklower * initiated by the receive interface. 28341591Ssklower */ 28441591Ssklower 28541591Ssklower if (PS(xp) != ((lcp -> lcd_rsn + 1) % MODULUS) || 28641591Ssklower PS(xp) == ((lcp -> lcd_input_window + lcp->lcd_windowsize) % MODULUS)) { 28741591Ssklower m_freem (m); 28845895Ssklower pk_procerror (RESET, lcp, "p(s) flow control error", 1); 28941591Ssklower break; 29041591Ssklower } 29141591Ssklower lcp -> lcd_rsn = PS(xp); 29241591Ssklower 29341591Ssklower if (pk_ack (lcp, PR(xp)) != PACKET_OK) { 29441591Ssklower m_freem (m); 29541591Ssklower break; 29641591Ssklower } 29745895Ssklower m -> m_data += PKHEADERLN; 29845895Ssklower m -> m_len -= PKHEADERLN; 29945895Ssklower m -> m_pkthdr.len -= PKHEADERLN; 30045895Ssklower 30145895Ssklower if (lcp -> lcd_flags & X25_MBS_HOLD) { 30245895Ssklower register struct mbuf *n = lcp -> lcd_cps; 30345895Ssklower int mbit = MBIT(xp); 30445895Ssklower octet q_and_d_bits; 30545895Ssklower 30645895Ssklower if (n) { 30745895Ssklower n -> m_pkthdr.len += m -> m_pkthdr.len; 30845895Ssklower while (n -> m_next) 30945895Ssklower n = n -> m_next; 31045895Ssklower n -> m_next = m; 31145895Ssklower m = lcp -> lcd_cps; 31245895Ssklower 31345895Ssklower if (lcp -> lcd_cpsmax && 31445895Ssklower n -> m_pkthdr.len > lcp -> lcd_cpsmax) { 31545895Ssklower pk_procerror (RESET, lcp, 31645895Ssklower "C.P.S. overflow", 128); 31745895Ssklower return; 31845895Ssklower } 31945895Ssklower q_and_d_bits = 0xc0 & *(octet *)xp; 32045895Ssklower xp = (struct x25_packet *) 32145895Ssklower (mtod(m, octet *) - PKHEADERLN); 32245895Ssklower *(octet *)xp |= q_and_d_bits; 32345895Ssklower } 32445895Ssklower if (mbit) { 32545895Ssklower lcp -> lcd_cps = m; 32647268Ssklower lcp -> lcd_rxcnt++; 32747268Ssklower pk_flowcontrol(lcp, 0, 1); 32845895Ssklower return; 32945895Ssklower } 33045895Ssklower lcp -> lcd_cps = 0; 33145895Ssklower } 33245297Ssklower if (so == 0) 33345297Ssklower break; 33441591Ssklower if (lcp -> lcd_flags & X25_MQBIT) { 33545573Ssklower octet t = (xp -> q_bit) ? t = 0x80 : 0; 33641591Ssklower 33745573Ssklower if (MBIT(xp)) 33845573Ssklower t |= 0x40; 33943361Ssklower m -> m_data -= 1; 34041591Ssklower m -> m_len += 1; 34145895Ssklower m -> m_pkthdr.len += 1; 34245573Ssklower *mtod(m, octet *) = t; 34341591Ssklower } 34441591Ssklower 34541591Ssklower /* 34641591Ssklower * Discard Q-BIT packets if the application 34741591Ssklower * doesn't want to be informed of M and Q bit status 34841591Ssklower */ 34941591Ssklower if (xp -> q_bit && (lcp -> lcd_flags & X25_MQBIT) == 0) { 35041591Ssklower m_freem (m); 35141591Ssklower lcp -> lcd_rxcnt++; 35241591Ssklower /* 35341591Ssklower * NB. This is dangerous: sending a RR here can 35441591Ssklower * cause sequence number errors if a previous data 35541591Ssklower * packet has not yet been passed up to the application 35641591Ssklower * (RR's are normally generated via PRU_RCVD). 35741591Ssklower */ 35847268Ssklower pk_flowcontrol(lcp, 0, 1); 35941591Ssklower } else { 36041591Ssklower sbappendrecord (&so -> so_rcv, m); 36141591Ssklower sorwakeup (so); 36241591Ssklower } 36341591Ssklower break; 36441591Ssklower 36541591Ssklower /* 36641591Ssklower * Interrupt packet received. 36741591Ssklower */ 36841591Ssklower case INTERRUPT + DATA_TRANSFER: 36941591Ssklower if (lcp -> lcd_reset_condition) 37041591Ssklower break; 37141591Ssklower lcp -> lcd_intrdata = xp -> packet_data; 37241591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM); 37341591Ssklower pk_output (lcp); 37445895Ssklower m -> m_data += PKHEADERLN; 37545895Ssklower m -> m_len -= PKHEADERLN; 37645895Ssklower m -> m_pkthdr.len -= PKHEADERLN; 37745297Ssklower MCHTYPE(m, MT_OOBDATA); 37845895Ssklower if (so) { 37945895Ssklower if (so -> so_options & SO_OOBINLINE) 38045895Ssklower sbinsertoob (&so -> so_rcv, m); 38145895Ssklower else 38245895Ssklower m_freem (m); 38345297Ssklower sohasoutofband (so); 38445895Ssklower } 38541591Ssklower break; 38641591Ssklower 38741591Ssklower /* 38841591Ssklower * Interrupt confirmation packet received. 38941591Ssklower */ 39041591Ssklower case INTERRUPT_CONF + DATA_TRANSFER: 39141591Ssklower if (lcp -> lcd_reset_condition) 39241591Ssklower break; 39341591Ssklower if (lcp -> lcd_intrconf_pending == TRUE) 39441591Ssklower lcp -> lcd_intrconf_pending = FALSE; 39541591Ssklower else 39645895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 43); 39741591Ssklower break; 39841591Ssklower 39941591Ssklower /* 40041591Ssklower * Receiver ready received. Rotate the output window and output 40141591Ssklower * any data packets waiting transmission. 40241591Ssklower */ 40341591Ssklower case RR + DATA_TRANSFER: 40445297Ssklower if (lcp -> lcd_reset_condition || 40545297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 40645297Ssklower ptype = DELETE_PACKET; 40741591Ssklower break; 40845297Ssklower } 40941591Ssklower if (lcp -> lcd_rnr_condition == TRUE) 41041591Ssklower lcp -> lcd_rnr_condition = FALSE; 41141591Ssklower pk_output (lcp); 41241591Ssklower break; 41341591Ssklower 41441591Ssklower /* 41541591Ssklower * Receiver Not Ready received. Packets up to the P(R) can be 41641591Ssklower * be sent. Condition is cleared with a RR. 41741591Ssklower */ 41841591Ssklower case RNR + DATA_TRANSFER: 41945297Ssklower if (lcp -> lcd_reset_condition || 42045297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 42145297Ssklower ptype = DELETE_PACKET; 42241591Ssklower break; 42345297Ssklower } 42441591Ssklower lcp -> lcd_rnr_condition = TRUE; 42541591Ssklower break; 42641591Ssklower 42741591Ssklower /* 42841591Ssklower * Reset packet received. Set state to FLOW_OPEN. The Input and 42941591Ssklower * Output window edges ar set to zero. Both the send and receive 43041591Ssklower * numbers are reset. A confirmation is returned. 43141591Ssklower */ 43241591Ssklower case RESET + DATA_TRANSFER: 43341591Ssklower if (lcp -> lcd_reset_condition) 43441591Ssklower /* Reset collision. Just ignore packet. */ 43541591Ssklower break; 43641591Ssklower 43741591Ssklower pk_resetcause (pkp, xp); 43841591Ssklower lcp -> lcd_window_condition = lcp -> lcd_rnr_condition = 43941591Ssklower lcp -> lcd_intrconf_pending = FALSE; 44041591Ssklower lcp -> lcd_output_window = lcp -> lcd_input_window = 44141591Ssklower lcp -> lcd_last_transmitted_pr = 0; 44241591Ssklower lcp -> lcd_ssn = 0; 44341591Ssklower lcp -> lcd_rsn = MODULUS - 1; 44441591Ssklower 44541591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM); 44641591Ssklower pk_output (lcp); 44745297Ssklower 44845895Ssklower pk_flush(lcp); 44945297Ssklower if (so == 0) 45045297Ssklower break; 45145297Ssklower wakeup ((caddr_t) & so -> so_timeo); 45245297Ssklower sorwakeup (so); 45345297Ssklower sowwakeup (so); 45441591Ssklower break; 45541591Ssklower 45641591Ssklower /* 45741591Ssklower * Reset confirmation received. 45841591Ssklower */ 45941591Ssklower case RESET_CONF + DATA_TRANSFER: 46041591Ssklower if (lcp -> lcd_reset_condition) { 46141591Ssklower lcp -> lcd_reset_condition = FALSE; 46241591Ssklower pk_output (lcp); 46341591Ssklower } 46441591Ssklower else 46545895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 32); 46641591Ssklower break; 46741591Ssklower 46841591Ssklower case DATA + SENT_CLEAR: 46941591Ssklower ptype = DELETE_PACKET; 47041591Ssklower case RR + SENT_CLEAR: 47141591Ssklower case RNR + SENT_CLEAR: 47241591Ssklower case INTERRUPT + SENT_CLEAR: 47341591Ssklower case INTERRUPT_CONF + SENT_CLEAR: 47441591Ssklower case RESET + SENT_CLEAR: 47541591Ssklower case RESET_CONF + SENT_CLEAR: 47645297Ssklower /* Just ignore p if we have sent a CLEAR already. 47741591Ssklower */ 47841591Ssklower break; 47941591Ssklower 48041591Ssklower /* 48141591Ssklower * Restart sets all the permanent virtual circuits to the "Data 48241591Ssklower * Transfer" stae and all the switched virtual circuits to the 48341591Ssklower * "Ready" state. 48441591Ssklower */ 48541591Ssklower case RESTART + READY: 48641591Ssklower switch (pkp -> pk_state) { 48741591Ssklower case DTE_SENT_RESTART: 48841591Ssklower /* Restart collision. */ 48941591Ssklower pkp -> pk_state = DTE_READY; 49041591Ssklower pk_message (0, pkp -> pk_xcp, 49141591Ssklower "Packet level operational"); 49241591Ssklower break; 49341591Ssklower 49441591Ssklower default: 49541591Ssklower pk_restart (pkp, -1); 49641591Ssklower pk_restartcause (pkp, xp); 49741591Ssklower pkp -> pk_chan[0] -> lcd_template = pk_template (0, 49841591Ssklower X25_RESTART_CONFIRM); 49941591Ssklower pk_output (pkp -> pk_chan[0]); 50041591Ssklower } 50141591Ssklower break; 50241591Ssklower 50341591Ssklower /* 50441591Ssklower * Restart confirmation received. All logical channels are set 50541591Ssklower * to READY. 50641591Ssklower */ 50741591Ssklower case RESTART_CONF + READY: 50841591Ssklower switch (pkp -> pk_state) { 50941591Ssklower case DTE_SENT_RESTART: 51041591Ssklower pkp -> pk_state = DTE_READY; 51141591Ssklower pk_message (0, pkp -> pk_xcp, 51241591Ssklower "Packet level operational"); 51341591Ssklower break; 51441591Ssklower 51541591Ssklower default: 51641591Ssklower /* Restart local procedure error. */ 51741591Ssklower pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR); 51841591Ssklower pkp -> pk_state = DTE_SENT_RESTART; 51941591Ssklower } 52041591Ssklower break; 52141591Ssklower 52241591Ssklower default: 52341591Ssklower if (lcp) { 52445895Ssklower pk_procerror (CLEAR, lcp, "unknown packet error", 33); 52541591Ssklower pk_message (lcn, pkp -> pk_xcp, 52641591Ssklower "\"%s\" unexpected in \"%s\" state", 52741591Ssklower pk_name[ptype/MAXSTATES], pk_state[lcdstate]); 52845895Ssklower } else 52945573Ssklower pk_message (lcn, pkp -> pk_xcp, 53041591Ssklower "packet arrived on unassigned lcn"); 53141591Ssklower break; 53241591Ssklower } 53349252Ssklower if (so == 0 && lcp && lcp -> lcd_upper && lcdstate == DATA_TRANSFER) { 53445895Ssklower if (ptype != DATA && ptype != INTERRUPT) 53545895Ssklower MCHTYPE(m, MT_CONTROL); 53645297Ssklower lcp -> lcd_upper (lcp, m); 53745895Ssklower } else if (ptype != DATA && ptype != INTERRUPT) 53841591Ssklower m_freem (m); 53941591Ssklower } 54041591Ssklower 54141591Ssklower 54241591Ssklower /* 54341591Ssklower * This routine handles incoming call packets. It matches the protocol 54441591Ssklower * field on the Call User Data field (usually the first four bytes) with 54541591Ssklower * sockets awaiting connections. 54641591Ssklower */ 54741591Ssklower 548*49593Ssklower pk_incoming_call (pkp, m0) 54945895Ssklower struct mbuf *m0; 55041591Ssklower struct pkcb *pkp; 55141591Ssklower { 55242277Ssklower register struct pklcd *lcp = 0, *l; 55341591Ssklower register struct sockaddr_x25 *sa; 55441591Ssklower register struct x25_calladdr *a; 55542277Ssklower register struct socket *so = 0; 55645895Ssklower struct x25_packet *xp = mtod(m0, struct x25_packet *); 55741591Ssklower struct mbuf *m; 55845895Ssklower int len = m0->m_pkthdr.len; 55941591Ssklower register int l1, l2; 56041591Ssklower char *e, *errstr = "server unavailable"; 56145895Ssklower octet *u, *facp; 56245573Ssklower int lcn = LCN(xp); 56341591Ssklower 56441591Ssklower /* First, copy the data from the incoming call packet to a X25_socket 56541591Ssklower descriptor. */ 56641591Ssklower 56741591Ssklower a = (struct x25_calladdr *) &xp -> packet_data; 56841591Ssklower l1 = a -> calling_addrlen; 56941591Ssklower l2 = a -> called_addrlen; 57045297Ssklower if ((m = m_getclr (M_DONTWAIT, MT_SONAME)) == 0) 57141591Ssklower return; 57241591Ssklower sa = mtod (m, struct sockaddr_x25 *); 57341591Ssklower u = (octet *) (a -> address_field + l2 / 2); 57441591Ssklower e = sa -> x25_addr; 57541591Ssklower if (l2 & 0x01) { 57641591Ssklower *e++ = *u++ & 0x0f; 57741591Ssklower l1--; 57841591Ssklower } 57941591Ssklower from_bcd (e, &u, l1); 58041591Ssklower if (l1 & 0x01) 58141591Ssklower u++; 58241591Ssklower 58345895Ssklower facp = u; 584*49593Ssklower pk_parse_facilities (u, sa); 58541591Ssklower u += *u + 1; 58641591Ssklower sa -> x25_udlen = min (16, ((octet *)xp) + len - u); 58741591Ssklower if (sa -> x25_udlen < 0) 58841591Ssklower sa -> x25_udlen = 0; 58941591Ssklower bcopy ((caddr_t)u, sa -> x25_udata, (unsigned)sa -> x25_udlen); 59041591Ssklower 59141591Ssklower /* 59241591Ssklower * Now, loop through the listen sockets looking for a match on the 59341591Ssklower * PID. That is the first four octets of the user data field. This 59441591Ssklower * is the closest thing to a port number for X.25 packets. What it 59541591Ssklower * does provide is away of multiplexing services at the user level. 59641591Ssklower */ 59741591Ssklower 59841591Ssklower for (l = pk_listenhead; l; l = l -> lcd_listen) { 59941591Ssklower struct sockaddr_x25 *sxp = l -> lcd_ceaddr; 60041591Ssklower 60141591Ssklower if (bcmp (sxp -> x25_udata, sa -> x25_udata, sxp->x25_udlen)) 60241591Ssklower continue; 60345165Ssklower if (sxp -> x25_net && 60445165Ssklower sxp -> x25_net != pkp->pk_xc.xc_addr.x25_net) 60541591Ssklower continue; 60641591Ssklower /* 60741591Ssklower * don't accept incoming collect calls unless 60841591Ssklower * the server sets the reverse charging option. 60941591Ssklower */ 61041591Ssklower if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 && 61141591Ssklower sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) { 61241591Ssklower errstr = "incoming collect call refused"; 61341591Ssklower break; 61441591Ssklower } 61545573Ssklower /* 61645573Ssklower * don't accept incoming calls with the D-Bit on 61745573Ssklower * unless the server agrees 61845573Ssklower */ 61945573Ssklower if (xp -> d_bit && !(sxp -> x25_opts.op_flags & X25_DBIT)) { 62045573Ssklower errstr = "incoming D-Bit mismatch"; 62145573Ssklower break; 62245573Ssklower } 62342277Ssklower if (l -> lcd_so) { 62445165Ssklower if (so = sonewconn (l -> lcd_so, SS_ISCONNECTED)) 62542277Ssklower lcp = (struct pklcd *) so -> so_pcb; 62642277Ssklower } else 62742277Ssklower lcp = pk_attach((struct socket *) 0); 62842277Ssklower if (lcp == 0) { 62941591Ssklower /* 63041591Ssklower * Insufficient space or too many unaccepted 63141591Ssklower * connections. Just throw the call away. 63241591Ssklower */ 63341591Ssklower errstr = "server malfunction"; 63441591Ssklower break; 63541591Ssklower } 63643361Ssklower lcp -> lcd_upper = l -> lcd_upper; 63743361Ssklower lcp -> lcd_upnext = l -> lcd_upnext; 63841591Ssklower lcp -> lcd_lcn = lcn; 63941591Ssklower lcp -> lcd_state = RECEIVED_CALL; 64041591Ssklower lcp -> lcd_craddr = sa; 64141591Ssklower sa -> x25_opts.op_flags |= sxp -> x25_opts.op_flags & 64241591Ssklower ~X25_REVERSE_CHARGE; 64341591Ssklower pk_assoc (pkp, lcp, sa); 64441591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED); 64545573Ssklower if (lcp -> lcd_flags & X25_DBIT) { 64645573Ssklower if (xp -> d_bit) 64745895Ssklower mtod(lcp -> lcd_template, 64845895Ssklower struct x25_packet *) -> d_bit = 1; 64945573Ssklower else 65045573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 65145573Ssklower } 65243361Ssklower if (so) { 65343361Ssklower pk_output (lcp); 65442277Ssklower soisconnected (so); 65545895Ssklower if (so -> so_options & SO_OOBINLINE) 65645895Ssklower save_extra(m0, facp, so); 65745895Ssklower } else if (lcp -> lcd_upper) { 65845895Ssklower m -> m_next = m0; 65945895Ssklower (*lcp -> lcd_upper) (lcp, m); 66045895Ssklower (void) m_free (m); /* only m; m0 freed by caller */ 66145895Ssklower } 66241591Ssklower return; 66341591Ssklower } 66441591Ssklower 66541591Ssklower /* 66641591Ssklower * If the call fails for whatever reason, we still need to build a 66741591Ssklower * skeleton LCD in order to be able to properly receive the CLEAR 66841591Ssklower * CONFIRMATION. 66941591Ssklower */ 67041591Ssklower #ifdef WATERLOO /* be explicit */ 67141591Ssklower if (l == 0 && bcmp(sa->x25_udata, "ean", 3) == 0) 67241591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s", 67341591Ssklower sa->x25_addr, sa->x25_udata[3] & 0xff, errstr); 67441591Ssklower else if (l == 0 && bcmp(sa->x25_udata, "\1\0\0\0", 4) == 0) 67541591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s", 67641591Ssklower sa->x25_addr, errstr); 67741591Ssklower else 67841591Ssklower #endif 67941591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s", 68041591Ssklower sa -> x25_addr, sa -> x25_udata[0] & 0xff, 68141591Ssklower sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff, 68241591Ssklower sa -> x25_udata[3] & 0xff, errstr); 68345297Ssklower if ((lcp = pk_attach((struct socket *)0)) == 0) { 68445297Ssklower (void) m_free (m); 68541591Ssklower return; 68641591Ssklower } 68741591Ssklower lcp -> lcd_lcn = lcn; 68841591Ssklower lcp -> lcd_state = RECEIVED_CALL; 68941591Ssklower pk_assoc (pkp, lcp, sa); 69045297Ssklower (void) m_free (m); 69145895Ssklower pk_clear (lcp, 0, 1); 69241591Ssklower } 69341591Ssklower 69441591Ssklower static 69545895Ssklower save_extra(m0, fp, so) 69645895Ssklower struct mbuf *m0; 69745895Ssklower octet *fp; 69845895Ssklower struct socket *so; 69945895Ssklower { 70045895Ssklower register struct mbuf *m; 70145895Ssklower struct cmsghdr cmsghdr; 70245895Ssklower if (m = m_copym (m, 0, (int)M_COPYALL)) { 70345895Ssklower int off = fp - mtod (m0, octet *); 70445895Ssklower int len = m->m_pkthdr.len - off + sizeof (cmsghdr); 70545895Ssklower cmsghdr.cmsg_len = len; 70645895Ssklower cmsghdr.cmsg_level = AF_CCITT; 70745895Ssklower cmsghdr.cmsg_type = PK_FACILITIES; 70845895Ssklower m_adj (m, off); 70945895Ssklower M_PREPEND (m, sizeof(cmsghdr), M_DONTWAIT); 71045895Ssklower if (m == 0) 71145895Ssklower return; 71245895Ssklower bcopy ((caddr_t)&cmsghdr, mtod (m, caddr_t), sizeof (cmsghdr)); 71345895Ssklower MCHTYPE(m, MT_CONTROL); 71445895Ssklower sbappendrecord(&so -> so_rcv, m); 71545895Ssklower } 71645895Ssklower } 71745895Ssklower 718*49593Ssklower pk_call_accepted (lcp, m) 71941591Ssklower struct pklcd *lcp; 72049252Ssklower struct mbuf *m; 72141591Ssklower { 72241591Ssklower register struct x25_calladdr *ap; 72341591Ssklower register octet *fcp; 72449252Ssklower struct x25_packet *xp = mtod (m, struct x25_packet *); 72549252Ssklower int len = m -> m_len; 72641591Ssklower 72741591Ssklower lcp -> lcd_state = DATA_TRANSFER; 72845297Ssklower if (lcp -> lcd_so) 72945297Ssklower soisconnected (lcp -> lcd_so); 73045573Ssklower if ((lcp -> lcd_flags & X25_DBIT) && (xp -> d_bit == 0)) 73145573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 73241591Ssklower if (len > 3) { 73341591Ssklower ap = (struct x25_calladdr *) &xp -> packet_data; 73441591Ssklower fcp = (octet *) ap -> address_field + (ap -> calling_addrlen + 73541591Ssklower ap -> called_addrlen + 1) / 2; 73641591Ssklower if (fcp + *fcp <= ((octet *)xp) + len) 737*49593Ssklower pk_parse_facilities (fcp, lcp -> lcd_ceaddr); 73841591Ssklower } 73941591Ssklower pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr); 74049252Ssklower if (lcp -> lcd_so == 0 && lcp -> lcd_upper) 74149252Ssklower lcp -> lcd_upper(lcp, m); 74241591Ssklower } 74341591Ssklower 744*49593Ssklower pk_parse_facilities (fcp, sa) 74541591Ssklower register octet *fcp; 74641591Ssklower register struct sockaddr_x25 *sa; 74741591Ssklower { 74841591Ssklower register octet *maxfcp; 74941591Ssklower 75041591Ssklower maxfcp = fcp + *fcp; 75141591Ssklower fcp++; 75241591Ssklower while (fcp < maxfcp) { 75341591Ssklower /* 75441591Ssklower * Ignore national DCE or DTE facilities 75541591Ssklower */ 75641591Ssklower if (*fcp == 0 || *fcp == 0xff) 75741591Ssklower break; 75841591Ssklower switch (*fcp) { 75941591Ssklower case FACILITIES_WINDOWSIZE: 76041591Ssklower sa -> x25_opts.op_wsize = fcp[1]; 76141591Ssklower fcp += 3; 76241591Ssklower break; 76341591Ssklower 76441591Ssklower case FACILITIES_PACKETSIZE: 76541591Ssklower sa -> x25_opts.op_psize = fcp[1]; 76641591Ssklower fcp += 3; 76741591Ssklower break; 76841591Ssklower 76941591Ssklower case FACILITIES_THROUGHPUT: 77041591Ssklower sa -> x25_opts.op_speed = fcp[1]; 77141591Ssklower fcp += 2; 77241591Ssklower break; 77341591Ssklower 77441591Ssklower case FACILITIES_REVERSE_CHARGE: 77541591Ssklower if (fcp[1] & 01) 77641591Ssklower sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE; 77741591Ssklower /* 77841591Ssklower * Datapac specific: for a X.25(1976) DTE, bit 2 77941591Ssklower * indicates a "hi priority" (eg. international) call. 78041591Ssklower */ 78141591Ssklower if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0) 78241591Ssklower sa -> x25_opts.op_psize = X25_PS128; 78341591Ssklower fcp += 2; 78441591Ssklower break; 78541591Ssklower 78641591Ssklower default: 78741591Ssklower /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/ 78841591Ssklower switch ((*fcp & 0xc0) >> 6) { 78941591Ssklower case 0: /* class A */ 79041591Ssklower fcp += 2; 79141591Ssklower break; 79241591Ssklower 79341591Ssklower case 1: 79441591Ssklower fcp += 3; 79541591Ssklower break; 79641591Ssklower 79741591Ssklower case 2: 79841591Ssklower fcp += 4; 79941591Ssklower break; 80041591Ssklower 80141591Ssklower case 3: 80241591Ssklower fcp++; 80341591Ssklower fcp += *fcp; 80441591Ssklower } 80541591Ssklower } 80641591Ssklower } 80741591Ssklower } 80841591Ssklower 80941591Ssklower from_bcd (a, x, len) 81041591Ssklower register char *a; 81141591Ssklower register octet **x; 81241591Ssklower register int len; 81341591Ssklower { 81441591Ssklower register int posn = 0; 81541591Ssklower 81641591Ssklower while (--len >= 0) { 81741591Ssklower if (posn++ & 0x01) 81841591Ssklower *a = *(*x)++ & 0x0f; 81941591Ssklower else 82041591Ssklower *a = (**x >> 4) & 0x0F; 82141591Ssklower *a++ |= 0x30; 82241591Ssklower } 82341591Ssklower } 824