141709Ssklower /* 241709Ssklower * Copyright (c) University of British Columbia, 1984 3*49252Ssklower * 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*49252Ssklower * @(#)pk_input.c 7.10 (Berkeley) 05/06/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 15745895Ssklower 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: 19245895Ssklower 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: 209*49252Ssklower MCHTYPE(m, MT_CONTROL); 210*49252Ssklower call_accepted (lcp, m); 21141591Ssklower break; 21241591Ssklower 21341591Ssklower /* 21441591Ssklower * This condition can only happen if the previous state was 21541591Ssklower * SENT_CALL. Just ignore the packet, eventually a clear 21641591Ssklower * confirmation should arrive. 21741591Ssklower */ 21841591Ssklower case CALL_ACCEPTED + SENT_CLEAR: 21941591Ssklower break; 22041591Ssklower 22141591Ssklower /* 22241591Ssklower * Clear packet received. This requires a complete tear down 22341591Ssklower * of the virtual circuit. Free buffers and control blocks. 22441591Ssklower * and send a clear confirmation. 22541591Ssklower */ 22641591Ssklower case CLEAR + READY: 22741591Ssklower case CLEAR + RECEIVED_CALL: 22841591Ssklower case CLEAR + SENT_CALL: 22941591Ssklower case CLEAR + DATA_TRANSFER: 23041591Ssklower lcp -> lcd_state = RECEIVED_CLEAR; 23141591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CLEAR_CONFIRM); 23241591Ssklower pk_output (lcp); 23341591Ssklower pk_clearcause (pkp, xp); 234*49252Ssklower if (lcp -> lcd_upper) { 235*49252Ssklower MCHTYPE(m, MT_CONTROL); 236*49252Ssklower lcp -> lcd_upper (lcp, m); 237*49252Ssklower } 23841591Ssklower pk_close (lcp); 239*49252Ssklower lcp = 0; 24041591Ssklower break; 24141591Ssklower 24241591Ssklower /* 24341591Ssklower * Clear collision: Treat this clear packet as a confirmation. 24441591Ssklower */ 24541591Ssklower case CLEAR + SENT_CLEAR: 24641591Ssklower pk_close (lcp); 24741591Ssklower break; 24841591Ssklower 24941591Ssklower /* 25041591Ssklower * Clear confirmation received. This usually means the virtual 25141591Ssklower * circuit is now completely removed. 25241591Ssklower */ 25341591Ssklower case CLEAR_CONF + SENT_CLEAR: 25441591Ssklower pk_close (lcp); 25541591Ssklower break; 25641591Ssklower 25741591Ssklower /* 25841591Ssklower * A clear confirmation on an unassigned logical channel - just 25941591Ssklower * ignore it. Note: All other packets on an unassigned channel 26041591Ssklower * results in a clear. 26141591Ssklower */ 26241591Ssklower case CLEAR_CONF + READY: 26341591Ssklower break; 26441591Ssklower 26541591Ssklower /* 26641591Ssklower * Data packet received. Pass on to next level. Move the Q and M 26741591Ssklower * bits into the data portion for the next level. 26841591Ssklower */ 26941591Ssklower case DATA + DATA_TRANSFER: 27041591Ssklower if (lcp -> lcd_reset_condition) { 27141591Ssklower ptype = DELETE_PACKET; 27241591Ssklower break; 27341591Ssklower } 27441591Ssklower 27541591Ssklower /* 27641591Ssklower * Process the P(S) flow control information in this Data packet. 27741591Ssklower * Check that the packets arrive in the correct sequence and that 27841591Ssklower * they are within the "lcd_input_window". Input window rotation is 27941591Ssklower * initiated by the receive interface. 28041591Ssklower */ 28141591Ssklower 28241591Ssklower if (PS(xp) != ((lcp -> lcd_rsn + 1) % MODULUS) || 28341591Ssklower PS(xp) == ((lcp -> lcd_input_window + lcp->lcd_windowsize) % MODULUS)) { 28441591Ssklower m_freem (m); 28545895Ssklower pk_procerror (RESET, lcp, "p(s) flow control error", 1); 28641591Ssklower break; 28741591Ssklower } 28841591Ssklower lcp -> lcd_rsn = PS(xp); 28941591Ssklower 29041591Ssklower if (pk_ack (lcp, PR(xp)) != PACKET_OK) { 29141591Ssklower m_freem (m); 29241591Ssklower break; 29341591Ssklower } 29445895Ssklower m -> m_data += PKHEADERLN; 29545895Ssklower m -> m_len -= PKHEADERLN; 29645895Ssklower m -> m_pkthdr.len -= PKHEADERLN; 29745895Ssklower 29845895Ssklower if (lcp -> lcd_flags & X25_MBS_HOLD) { 29945895Ssklower register struct mbuf *n = lcp -> lcd_cps; 30045895Ssklower int mbit = MBIT(xp); 30145895Ssklower octet q_and_d_bits; 30245895Ssklower 30345895Ssklower if (n) { 30445895Ssklower n -> m_pkthdr.len += m -> m_pkthdr.len; 30545895Ssklower while (n -> m_next) 30645895Ssklower n = n -> m_next; 30745895Ssklower n -> m_next = m; 30845895Ssklower m = lcp -> lcd_cps; 30945895Ssklower 31045895Ssklower if (lcp -> lcd_cpsmax && 31145895Ssklower n -> m_pkthdr.len > lcp -> lcd_cpsmax) { 31245895Ssklower pk_procerror (RESET, lcp, 31345895Ssklower "C.P.S. overflow", 128); 31445895Ssklower return; 31545895Ssklower } 31645895Ssklower q_and_d_bits = 0xc0 & *(octet *)xp; 31745895Ssklower xp = (struct x25_packet *) 31845895Ssklower (mtod(m, octet *) - PKHEADERLN); 31945895Ssklower *(octet *)xp |= q_and_d_bits; 32045895Ssklower } 32145895Ssklower if (mbit) { 32245895Ssklower lcp -> lcd_cps = m; 32347268Ssklower lcp -> lcd_rxcnt++; 32447268Ssklower pk_flowcontrol(lcp, 0, 1); 32545895Ssklower return; 32645895Ssklower } 32745895Ssklower lcp -> lcd_cps = 0; 32845895Ssklower } 32945297Ssklower if (so == 0) 33045297Ssklower break; 33141591Ssklower if (lcp -> lcd_flags & X25_MQBIT) { 33245573Ssklower octet t = (xp -> q_bit) ? t = 0x80 : 0; 33341591Ssklower 33445573Ssklower if (MBIT(xp)) 33545573Ssklower t |= 0x40; 33643361Ssklower m -> m_data -= 1; 33741591Ssklower m -> m_len += 1; 33845895Ssklower m -> m_pkthdr.len += 1; 33945573Ssklower *mtod(m, octet *) = t; 34041591Ssklower } 34141591Ssklower 34241591Ssklower /* 34341591Ssklower * Discard Q-BIT packets if the application 34441591Ssklower * doesn't want to be informed of M and Q bit status 34541591Ssklower */ 34641591Ssklower if (xp -> q_bit && (lcp -> lcd_flags & X25_MQBIT) == 0) { 34741591Ssklower m_freem (m); 34841591Ssklower lcp -> lcd_rxcnt++; 34941591Ssklower /* 35041591Ssklower * NB. This is dangerous: sending a RR here can 35141591Ssklower * cause sequence number errors if a previous data 35241591Ssklower * packet has not yet been passed up to the application 35341591Ssklower * (RR's are normally generated via PRU_RCVD). 35441591Ssklower */ 35547268Ssklower pk_flowcontrol(lcp, 0, 1); 35641591Ssklower } else { 35741591Ssklower sbappendrecord (&so -> so_rcv, m); 35841591Ssklower sorwakeup (so); 35941591Ssklower } 36041591Ssklower break; 36141591Ssklower 36241591Ssklower /* 36341591Ssklower * Interrupt packet received. 36441591Ssklower */ 36541591Ssklower case INTERRUPT + DATA_TRANSFER: 36641591Ssklower if (lcp -> lcd_reset_condition) 36741591Ssklower break; 36841591Ssklower lcp -> lcd_intrdata = xp -> packet_data; 36941591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM); 37041591Ssklower pk_output (lcp); 37145895Ssklower m -> m_data += PKHEADERLN; 37245895Ssklower m -> m_len -= PKHEADERLN; 37345895Ssklower m -> m_pkthdr.len -= PKHEADERLN; 37445297Ssklower MCHTYPE(m, MT_OOBDATA); 37545895Ssklower if (so) { 37645895Ssklower if (so -> so_options & SO_OOBINLINE) 37745895Ssklower sbinsertoob (&so -> so_rcv, m); 37845895Ssklower else 37945895Ssklower m_freem (m); 38045297Ssklower sohasoutofband (so); 38145895Ssklower } 38241591Ssklower break; 38341591Ssklower 38441591Ssklower /* 38541591Ssklower * Interrupt confirmation packet received. 38641591Ssklower */ 38741591Ssklower case INTERRUPT_CONF + DATA_TRANSFER: 38841591Ssklower if (lcp -> lcd_reset_condition) 38941591Ssklower break; 39041591Ssklower if (lcp -> lcd_intrconf_pending == TRUE) 39141591Ssklower lcp -> lcd_intrconf_pending = FALSE; 39241591Ssklower else 39345895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 43); 39441591Ssklower break; 39541591Ssklower 39641591Ssklower /* 39741591Ssklower * Receiver ready received. Rotate the output window and output 39841591Ssklower * any data packets waiting transmission. 39941591Ssklower */ 40041591Ssklower case RR + DATA_TRANSFER: 40145297Ssklower if (lcp -> lcd_reset_condition || 40245297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 40345297Ssklower ptype = DELETE_PACKET; 40441591Ssklower break; 40545297Ssklower } 40641591Ssklower if (lcp -> lcd_rnr_condition == TRUE) 40741591Ssklower lcp -> lcd_rnr_condition = FALSE; 40841591Ssklower pk_output (lcp); 40941591Ssklower break; 41041591Ssklower 41141591Ssklower /* 41241591Ssklower * Receiver Not Ready received. Packets up to the P(R) can be 41341591Ssklower * be sent. Condition is cleared with a RR. 41441591Ssklower */ 41541591Ssklower case RNR + DATA_TRANSFER: 41645297Ssklower if (lcp -> lcd_reset_condition || 41745297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 41845297Ssklower ptype = DELETE_PACKET; 41941591Ssklower break; 42045297Ssklower } 42141591Ssklower lcp -> lcd_rnr_condition = TRUE; 42241591Ssklower break; 42341591Ssklower 42441591Ssklower /* 42541591Ssklower * Reset packet received. Set state to FLOW_OPEN. The Input and 42641591Ssklower * Output window edges ar set to zero. Both the send and receive 42741591Ssklower * numbers are reset. A confirmation is returned. 42841591Ssklower */ 42941591Ssklower case RESET + DATA_TRANSFER: 43041591Ssklower if (lcp -> lcd_reset_condition) 43141591Ssklower /* Reset collision. Just ignore packet. */ 43241591Ssklower break; 43341591Ssklower 43441591Ssklower pk_resetcause (pkp, xp); 43541591Ssklower lcp -> lcd_window_condition = lcp -> lcd_rnr_condition = 43641591Ssklower lcp -> lcd_intrconf_pending = FALSE; 43741591Ssklower lcp -> lcd_output_window = lcp -> lcd_input_window = 43841591Ssklower lcp -> lcd_last_transmitted_pr = 0; 43941591Ssklower lcp -> lcd_ssn = 0; 44041591Ssklower lcp -> lcd_rsn = MODULUS - 1; 44141591Ssklower 44241591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM); 44341591Ssklower pk_output (lcp); 44445297Ssklower 44545895Ssklower pk_flush(lcp); 44645297Ssklower if (so == 0) 44745297Ssklower break; 44845297Ssklower wakeup ((caddr_t) & so -> so_timeo); 44945297Ssklower sorwakeup (so); 45045297Ssklower sowwakeup (so); 45141591Ssklower break; 45241591Ssklower 45341591Ssklower /* 45441591Ssklower * Reset confirmation received. 45541591Ssklower */ 45641591Ssklower case RESET_CONF + DATA_TRANSFER: 45741591Ssklower if (lcp -> lcd_reset_condition) { 45841591Ssklower lcp -> lcd_reset_condition = FALSE; 45941591Ssklower pk_output (lcp); 46041591Ssklower } 46141591Ssklower else 46245895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 32); 46341591Ssklower break; 46441591Ssklower 46541591Ssklower case DATA + SENT_CLEAR: 46641591Ssklower ptype = DELETE_PACKET; 46741591Ssklower case RR + SENT_CLEAR: 46841591Ssklower case RNR + SENT_CLEAR: 46941591Ssklower case INTERRUPT + SENT_CLEAR: 47041591Ssklower case INTERRUPT_CONF + SENT_CLEAR: 47141591Ssklower case RESET + SENT_CLEAR: 47241591Ssklower case RESET_CONF + SENT_CLEAR: 47345297Ssklower /* Just ignore p if we have sent a CLEAR already. 47441591Ssklower */ 47541591Ssklower break; 47641591Ssklower 47741591Ssklower /* 47841591Ssklower * Restart sets all the permanent virtual circuits to the "Data 47941591Ssklower * Transfer" stae and all the switched virtual circuits to the 48041591Ssklower * "Ready" state. 48141591Ssklower */ 48241591Ssklower case RESTART + READY: 48341591Ssklower switch (pkp -> pk_state) { 48441591Ssklower case DTE_SENT_RESTART: 48541591Ssklower /* Restart collision. */ 48641591Ssklower pkp -> pk_state = DTE_READY; 48741591Ssklower pk_message (0, pkp -> pk_xcp, 48841591Ssklower "Packet level operational"); 48941591Ssklower break; 49041591Ssklower 49141591Ssklower default: 49241591Ssklower pk_restart (pkp, -1); 49341591Ssklower pk_restartcause (pkp, xp); 49441591Ssklower pkp -> pk_chan[0] -> lcd_template = pk_template (0, 49541591Ssklower X25_RESTART_CONFIRM); 49641591Ssklower pk_output (pkp -> pk_chan[0]); 49741591Ssklower } 49841591Ssklower break; 49941591Ssklower 50041591Ssklower /* 50141591Ssklower * Restart confirmation received. All logical channels are set 50241591Ssklower * to READY. 50341591Ssklower */ 50441591Ssklower case RESTART_CONF + READY: 50541591Ssklower switch (pkp -> pk_state) { 50641591Ssklower case DTE_SENT_RESTART: 50741591Ssklower pkp -> pk_state = DTE_READY; 50841591Ssklower pk_message (0, pkp -> pk_xcp, 50941591Ssklower "Packet level operational"); 51041591Ssklower break; 51141591Ssklower 51241591Ssklower default: 51341591Ssklower /* Restart local procedure error. */ 51441591Ssklower pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR); 51541591Ssklower pkp -> pk_state = DTE_SENT_RESTART; 51641591Ssklower } 51741591Ssklower break; 51841591Ssklower 51941591Ssklower default: 52041591Ssklower if (lcp) { 52145895Ssklower pk_procerror (CLEAR, lcp, "unknown packet error", 33); 52241591Ssklower pk_message (lcn, pkp -> pk_xcp, 52341591Ssklower "\"%s\" unexpected in \"%s\" state", 52441591Ssklower pk_name[ptype/MAXSTATES], pk_state[lcdstate]); 52545895Ssklower } else 52645573Ssklower pk_message (lcn, pkp -> pk_xcp, 52741591Ssklower "packet arrived on unassigned lcn"); 52841591Ssklower break; 52941591Ssklower } 530*49252Ssklower if (so == 0 && lcp && lcp -> lcd_upper && lcdstate == DATA_TRANSFER) { 53145895Ssklower if (ptype != DATA && ptype != INTERRUPT) 53245895Ssklower MCHTYPE(m, MT_CONTROL); 53345297Ssklower lcp -> lcd_upper (lcp, m); 53445895Ssklower } else if (ptype != DATA && ptype != INTERRUPT) 53541591Ssklower m_freem (m); 53641591Ssklower } 53741591Ssklower 53841591Ssklower 53941591Ssklower /* 54041591Ssklower * This routine handles incoming call packets. It matches the protocol 54141591Ssklower * field on the Call User Data field (usually the first four bytes) with 54241591Ssklower * sockets awaiting connections. 54341591Ssklower */ 54441591Ssklower 54541591Ssklower static 54645895Ssklower incoming_call (pkp, m0) 54745895Ssklower struct mbuf *m0; 54841591Ssklower struct pkcb *pkp; 54941591Ssklower { 55042277Ssklower register struct pklcd *lcp = 0, *l; 55141591Ssklower register struct sockaddr_x25 *sa; 55241591Ssklower register struct x25_calladdr *a; 55342277Ssklower register struct socket *so = 0; 55445895Ssklower struct x25_packet *xp = mtod(m0, struct x25_packet *); 55541591Ssklower struct mbuf *m; 55645895Ssklower int len = m0->m_pkthdr.len; 55741591Ssklower register int l1, l2; 55841591Ssklower char *e, *errstr = "server unavailable"; 55945895Ssklower octet *u, *facp; 56045573Ssklower int lcn = LCN(xp); 56141591Ssklower 56241591Ssklower /* First, copy the data from the incoming call packet to a X25_socket 56341591Ssklower descriptor. */ 56441591Ssklower 56541591Ssklower a = (struct x25_calladdr *) &xp -> packet_data; 56641591Ssklower l1 = a -> calling_addrlen; 56741591Ssklower l2 = a -> called_addrlen; 56845297Ssklower if ((m = m_getclr (M_DONTWAIT, MT_SONAME)) == 0) 56941591Ssklower return; 57041591Ssklower sa = mtod (m, struct sockaddr_x25 *); 57141591Ssklower u = (octet *) (a -> address_field + l2 / 2); 57241591Ssklower e = sa -> x25_addr; 57341591Ssklower if (l2 & 0x01) { 57441591Ssklower *e++ = *u++ & 0x0f; 57541591Ssklower l1--; 57641591Ssklower } 57741591Ssklower from_bcd (e, &u, l1); 57841591Ssklower if (l1 & 0x01) 57941591Ssklower u++; 58041591Ssklower 58145895Ssklower facp = u; 58241591Ssklower parse_facilities (u, sa); 58341591Ssklower u += *u + 1; 58441591Ssklower sa -> x25_udlen = min (16, ((octet *)xp) + len - u); 58541591Ssklower if (sa -> x25_udlen < 0) 58641591Ssklower sa -> x25_udlen = 0; 58741591Ssklower bcopy ((caddr_t)u, sa -> x25_udata, (unsigned)sa -> x25_udlen); 58841591Ssklower 58941591Ssklower /* 59041591Ssklower * Now, loop through the listen sockets looking for a match on the 59141591Ssklower * PID. That is the first four octets of the user data field. This 59241591Ssklower * is the closest thing to a port number for X.25 packets. What it 59341591Ssklower * does provide is away of multiplexing services at the user level. 59441591Ssklower */ 59541591Ssklower 59641591Ssklower for (l = pk_listenhead; l; l = l -> lcd_listen) { 59741591Ssklower struct sockaddr_x25 *sxp = l -> lcd_ceaddr; 59841591Ssklower 59941591Ssklower if (bcmp (sxp -> x25_udata, sa -> x25_udata, sxp->x25_udlen)) 60041591Ssklower continue; 60145165Ssklower if (sxp -> x25_net && 60245165Ssklower sxp -> x25_net != pkp->pk_xc.xc_addr.x25_net) 60341591Ssklower continue; 60441591Ssklower /* 60541591Ssklower * don't accept incoming collect calls unless 60641591Ssklower * the server sets the reverse charging option. 60741591Ssklower */ 60841591Ssklower if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 && 60941591Ssklower sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) { 61041591Ssklower errstr = "incoming collect call refused"; 61141591Ssklower break; 61241591Ssklower } 61345573Ssklower /* 61445573Ssklower * don't accept incoming calls with the D-Bit on 61545573Ssklower * unless the server agrees 61645573Ssklower */ 61745573Ssklower if (xp -> d_bit && !(sxp -> x25_opts.op_flags & X25_DBIT)) { 61845573Ssklower errstr = "incoming D-Bit mismatch"; 61945573Ssklower break; 62045573Ssklower } 62142277Ssklower if (l -> lcd_so) { 62245165Ssklower if (so = sonewconn (l -> lcd_so, SS_ISCONNECTED)) 62342277Ssklower lcp = (struct pklcd *) so -> so_pcb; 62442277Ssklower } else 62542277Ssklower lcp = pk_attach((struct socket *) 0); 62642277Ssklower if (lcp == 0) { 62741591Ssklower /* 62841591Ssklower * Insufficient space or too many unaccepted 62941591Ssklower * connections. Just throw the call away. 63041591Ssklower */ 63141591Ssklower errstr = "server malfunction"; 63241591Ssklower break; 63341591Ssklower } 63443361Ssklower lcp -> lcd_upper = l -> lcd_upper; 63543361Ssklower lcp -> lcd_upnext = l -> lcd_upnext; 63641591Ssklower lcp -> lcd_lcn = lcn; 63741591Ssklower lcp -> lcd_state = RECEIVED_CALL; 63841591Ssklower lcp -> lcd_craddr = sa; 63941591Ssklower sa -> x25_opts.op_flags |= sxp -> x25_opts.op_flags & 64041591Ssklower ~X25_REVERSE_CHARGE; 64141591Ssklower pk_assoc (pkp, lcp, sa); 64241591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED); 64345573Ssklower if (lcp -> lcd_flags & X25_DBIT) { 64445573Ssklower if (xp -> d_bit) 64545895Ssklower mtod(lcp -> lcd_template, 64645895Ssklower struct x25_packet *) -> d_bit = 1; 64745573Ssklower else 64845573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 64945573Ssklower } 65043361Ssklower if (so) { 65143361Ssklower pk_output (lcp); 65242277Ssklower soisconnected (so); 65345895Ssklower if (so -> so_options & SO_OOBINLINE) 65445895Ssklower save_extra(m0, facp, so); 65545895Ssklower } else if (lcp -> lcd_upper) { 65645895Ssklower m -> m_next = m0; 65745895Ssklower (*lcp -> lcd_upper) (lcp, m); 65845895Ssklower (void) m_free (m); /* only m; m0 freed by caller */ 65945895Ssklower } 66041591Ssklower return; 66141591Ssklower } 66241591Ssklower 66341591Ssklower /* 66441591Ssklower * If the call fails for whatever reason, we still need to build a 66541591Ssklower * skeleton LCD in order to be able to properly receive the CLEAR 66641591Ssklower * CONFIRMATION. 66741591Ssklower */ 66841591Ssklower #ifdef WATERLOO /* be explicit */ 66941591Ssklower if (l == 0 && bcmp(sa->x25_udata, "ean", 3) == 0) 67041591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s", 67141591Ssklower sa->x25_addr, sa->x25_udata[3] & 0xff, errstr); 67241591Ssklower else if (l == 0 && bcmp(sa->x25_udata, "\1\0\0\0", 4) == 0) 67341591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s", 67441591Ssklower sa->x25_addr, errstr); 67541591Ssklower else 67641591Ssklower #endif 67741591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s", 67841591Ssklower sa -> x25_addr, sa -> x25_udata[0] & 0xff, 67941591Ssklower sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff, 68041591Ssklower sa -> x25_udata[3] & 0xff, errstr); 68145297Ssklower if ((lcp = pk_attach((struct socket *)0)) == 0) { 68245297Ssklower (void) m_free (m); 68341591Ssklower return; 68441591Ssklower } 68541591Ssklower lcp -> lcd_lcn = lcn; 68641591Ssklower lcp -> lcd_state = RECEIVED_CALL; 68741591Ssklower pk_assoc (pkp, lcp, sa); 68845297Ssklower (void) m_free (m); 68945895Ssklower pk_clear (lcp, 0, 1); 69041591Ssklower } 69141591Ssklower 69241591Ssklower static 69345895Ssklower save_extra(m0, fp, so) 69445895Ssklower struct mbuf *m0; 69545895Ssklower octet *fp; 69645895Ssklower struct socket *so; 69745895Ssklower { 69845895Ssklower register struct mbuf *m; 69945895Ssklower struct cmsghdr cmsghdr; 70045895Ssklower if (m = m_copym (m, 0, (int)M_COPYALL)) { 70145895Ssklower int off = fp - mtod (m0, octet *); 70245895Ssklower int len = m->m_pkthdr.len - off + sizeof (cmsghdr); 70345895Ssklower cmsghdr.cmsg_len = len; 70445895Ssklower cmsghdr.cmsg_level = AF_CCITT; 70545895Ssklower cmsghdr.cmsg_type = PK_FACILITIES; 70645895Ssklower m_adj (m, off); 70745895Ssklower M_PREPEND (m, sizeof(cmsghdr), M_DONTWAIT); 70845895Ssklower if (m == 0) 70945895Ssklower return; 71045895Ssklower bcopy ((caddr_t)&cmsghdr, mtod (m, caddr_t), sizeof (cmsghdr)); 71145895Ssklower MCHTYPE(m, MT_CONTROL); 71245895Ssklower sbappendrecord(&so -> so_rcv, m); 71345895Ssklower } 71445895Ssklower } 71545895Ssklower 71645895Ssklower static 717*49252Ssklower call_accepted (lcp, m) 71841591Ssklower struct pklcd *lcp; 719*49252Ssklower struct mbuf *m; 72041591Ssklower { 72141591Ssklower register struct x25_calladdr *ap; 72241591Ssklower register octet *fcp; 723*49252Ssklower struct x25_packet *xp = mtod (m, struct x25_packet *); 724*49252Ssklower int len = m -> m_len; 72541591Ssklower 72641591Ssklower lcp -> lcd_state = DATA_TRANSFER; 72745297Ssklower if (lcp -> lcd_so) 72845297Ssklower soisconnected (lcp -> lcd_so); 72945573Ssklower if ((lcp -> lcd_flags & X25_DBIT) && (xp -> d_bit == 0)) 73045573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 73141591Ssklower if (len > 3) { 73241591Ssklower ap = (struct x25_calladdr *) &xp -> packet_data; 73341591Ssklower fcp = (octet *) ap -> address_field + (ap -> calling_addrlen + 73441591Ssklower ap -> called_addrlen + 1) / 2; 73541591Ssklower if (fcp + *fcp <= ((octet *)xp) + len) 73641591Ssklower parse_facilities (fcp, lcp -> lcd_ceaddr); 73741591Ssklower } 73841591Ssklower pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr); 739*49252Ssklower if (lcp -> lcd_so == 0 && lcp -> lcd_upper) 740*49252Ssklower lcp -> lcd_upper(lcp, m); 74141591Ssklower } 74241591Ssklower 74341591Ssklower static 74441591Ssklower 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