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*47268Ssklower * @(#)pk_input.c 7.9 (Berkeley) 03/12/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: 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); 27945895Ssklower 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 } 28845895Ssklower m -> m_data += PKHEADERLN; 28945895Ssklower m -> m_len -= PKHEADERLN; 29045895Ssklower m -> m_pkthdr.len -= PKHEADERLN; 29145895Ssklower 29245895Ssklower if (lcp -> lcd_flags & X25_MBS_HOLD) { 29345895Ssklower register struct mbuf *n = lcp -> lcd_cps; 29445895Ssklower int mbit = MBIT(xp); 29545895Ssklower octet q_and_d_bits; 29645895Ssklower 29745895Ssklower if (n) { 29845895Ssklower n -> m_pkthdr.len += m -> m_pkthdr.len; 29945895Ssklower while (n -> m_next) 30045895Ssklower n = n -> m_next; 30145895Ssklower n -> m_next = m; 30245895Ssklower m = lcp -> lcd_cps; 30345895Ssklower 30445895Ssklower if (lcp -> lcd_cpsmax && 30545895Ssklower n -> m_pkthdr.len > lcp -> lcd_cpsmax) { 30645895Ssklower pk_procerror (RESET, lcp, 30745895Ssklower "C.P.S. overflow", 128); 30845895Ssklower return; 30945895Ssklower } 31045895Ssklower q_and_d_bits = 0xc0 & *(octet *)xp; 31145895Ssklower xp = (struct x25_packet *) 31245895Ssklower (mtod(m, octet *) - PKHEADERLN); 31345895Ssklower *(octet *)xp |= q_and_d_bits; 31445895Ssklower } 31545895Ssklower if (mbit) { 31645895Ssklower lcp -> lcd_cps = m; 317*47268Ssklower lcp -> lcd_rxcnt++; 318*47268Ssklower pk_flowcontrol(lcp, 0, 1); 31945895Ssklower return; 32045895Ssklower } 32145895Ssklower lcp -> lcd_cps = 0; 32245895Ssklower } 32345297Ssklower if (so == 0) 32445297Ssklower break; 32541591Ssklower if (lcp -> lcd_flags & X25_MQBIT) { 32645573Ssklower octet t = (xp -> q_bit) ? t = 0x80 : 0; 32741591Ssklower 32845573Ssklower if (MBIT(xp)) 32945573Ssklower t |= 0x40; 33043361Ssklower m -> m_data -= 1; 33141591Ssklower m -> m_len += 1; 33245895Ssklower m -> m_pkthdr.len += 1; 33345573Ssklower *mtod(m, octet *) = t; 33441591Ssklower } 33541591Ssklower 33641591Ssklower /* 33741591Ssklower * Discard Q-BIT packets if the application 33841591Ssklower * doesn't want to be informed of M and Q bit status 33941591Ssklower */ 34041591Ssklower if (xp -> q_bit && (lcp -> lcd_flags & X25_MQBIT) == 0) { 34141591Ssklower m_freem (m); 34241591Ssklower lcp -> lcd_rxcnt++; 34341591Ssklower /* 34441591Ssklower * NB. This is dangerous: sending a RR here can 34541591Ssklower * cause sequence number errors if a previous data 34641591Ssklower * packet has not yet been passed up to the application 34741591Ssklower * (RR's are normally generated via PRU_RCVD). 34841591Ssklower */ 349*47268Ssklower pk_flowcontrol(lcp, 0, 1); 35041591Ssklower } else { 35141591Ssklower sbappendrecord (&so -> so_rcv, m); 35241591Ssklower sorwakeup (so); 35341591Ssklower } 35441591Ssklower break; 35541591Ssklower 35641591Ssklower /* 35741591Ssklower * Interrupt packet received. 35841591Ssklower */ 35941591Ssklower case INTERRUPT + DATA_TRANSFER: 36041591Ssklower if (lcp -> lcd_reset_condition) 36141591Ssklower break; 36241591Ssklower lcp -> lcd_intrdata = xp -> packet_data; 36341591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM); 36441591Ssklower pk_output (lcp); 36545895Ssklower m -> m_data += PKHEADERLN; 36645895Ssklower m -> m_len -= PKHEADERLN; 36745895Ssklower m -> m_pkthdr.len -= PKHEADERLN; 36845297Ssklower MCHTYPE(m, MT_OOBDATA); 36945895Ssklower if (so) { 37045895Ssklower if (so -> so_options & SO_OOBINLINE) 37145895Ssklower sbinsertoob (&so -> so_rcv, m); 37245895Ssklower else 37345895Ssklower m_freem (m); 37445297Ssklower sohasoutofband (so); 37545895Ssklower } 37641591Ssklower break; 37741591Ssklower 37841591Ssklower /* 37941591Ssklower * Interrupt confirmation packet received. 38041591Ssklower */ 38141591Ssklower case INTERRUPT_CONF + DATA_TRANSFER: 38241591Ssklower if (lcp -> lcd_reset_condition) 38341591Ssklower break; 38441591Ssklower if (lcp -> lcd_intrconf_pending == TRUE) 38541591Ssklower lcp -> lcd_intrconf_pending = FALSE; 38641591Ssklower else 38745895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 43); 38841591Ssklower break; 38941591Ssklower 39041591Ssklower /* 39141591Ssklower * Receiver ready received. Rotate the output window and output 39241591Ssklower * any data packets waiting transmission. 39341591Ssklower */ 39441591Ssklower case RR + DATA_TRANSFER: 39545297Ssklower if (lcp -> lcd_reset_condition || 39645297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 39745297Ssklower ptype = DELETE_PACKET; 39841591Ssklower break; 39945297Ssklower } 40041591Ssklower if (lcp -> lcd_rnr_condition == TRUE) 40141591Ssklower lcp -> lcd_rnr_condition = FALSE; 40241591Ssklower pk_output (lcp); 40341591Ssklower break; 40441591Ssklower 40541591Ssklower /* 40641591Ssklower * Receiver Not Ready received. Packets up to the P(R) can be 40741591Ssklower * be sent. Condition is cleared with a RR. 40841591Ssklower */ 40941591Ssklower case RNR + DATA_TRANSFER: 41045297Ssklower if (lcp -> lcd_reset_condition || 41145297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 41245297Ssklower ptype = DELETE_PACKET; 41341591Ssklower break; 41445297Ssklower } 41541591Ssklower lcp -> lcd_rnr_condition = TRUE; 41641591Ssklower break; 41741591Ssklower 41841591Ssklower /* 41941591Ssklower * Reset packet received. Set state to FLOW_OPEN. The Input and 42041591Ssklower * Output window edges ar set to zero. Both the send and receive 42141591Ssklower * numbers are reset. A confirmation is returned. 42241591Ssklower */ 42341591Ssklower case RESET + DATA_TRANSFER: 42441591Ssklower if (lcp -> lcd_reset_condition) 42541591Ssklower /* Reset collision. Just ignore packet. */ 42641591Ssklower break; 42741591Ssklower 42841591Ssklower pk_resetcause (pkp, xp); 42941591Ssklower lcp -> lcd_window_condition = lcp -> lcd_rnr_condition = 43041591Ssklower lcp -> lcd_intrconf_pending = FALSE; 43141591Ssklower lcp -> lcd_output_window = lcp -> lcd_input_window = 43241591Ssklower lcp -> lcd_last_transmitted_pr = 0; 43341591Ssklower lcp -> lcd_ssn = 0; 43441591Ssklower lcp -> lcd_rsn = MODULUS - 1; 43541591Ssklower 43641591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM); 43741591Ssklower pk_output (lcp); 43845297Ssklower 43945895Ssklower pk_flush(lcp); 44045297Ssklower if (so == 0) 44145297Ssklower break; 44245297Ssklower wakeup ((caddr_t) & so -> so_timeo); 44345297Ssklower sorwakeup (so); 44445297Ssklower sowwakeup (so); 44541591Ssklower break; 44641591Ssklower 44741591Ssklower /* 44841591Ssklower * Reset confirmation received. 44941591Ssklower */ 45041591Ssklower case RESET_CONF + DATA_TRANSFER: 45141591Ssklower if (lcp -> lcd_reset_condition) { 45241591Ssklower lcp -> lcd_reset_condition = FALSE; 45341591Ssklower pk_output (lcp); 45441591Ssklower } 45541591Ssklower else 45645895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 32); 45741591Ssklower break; 45841591Ssklower 45941591Ssklower case DATA + SENT_CLEAR: 46041591Ssklower ptype = DELETE_PACKET; 46141591Ssklower case RR + SENT_CLEAR: 46241591Ssklower case RNR + SENT_CLEAR: 46341591Ssklower case INTERRUPT + SENT_CLEAR: 46441591Ssklower case INTERRUPT_CONF + SENT_CLEAR: 46541591Ssklower case RESET + SENT_CLEAR: 46641591Ssklower case RESET_CONF + SENT_CLEAR: 46745297Ssklower /* Just ignore p if we have sent a CLEAR already. 46841591Ssklower */ 46941591Ssklower break; 47041591Ssklower 47141591Ssklower /* 47241591Ssklower * Restart sets all the permanent virtual circuits to the "Data 47341591Ssklower * Transfer" stae and all the switched virtual circuits to the 47441591Ssklower * "Ready" state. 47541591Ssklower */ 47641591Ssklower case RESTART + READY: 47741591Ssklower switch (pkp -> pk_state) { 47841591Ssklower case DTE_SENT_RESTART: 47941591Ssklower /* Restart collision. */ 48041591Ssklower pkp -> pk_state = DTE_READY; 48141591Ssklower pk_message (0, pkp -> pk_xcp, 48241591Ssklower "Packet level operational"); 48341591Ssklower break; 48441591Ssklower 48541591Ssklower default: 48641591Ssklower pk_restart (pkp, -1); 48741591Ssklower pk_restartcause (pkp, xp); 48841591Ssklower pkp -> pk_chan[0] -> lcd_template = pk_template (0, 48941591Ssklower X25_RESTART_CONFIRM); 49041591Ssklower pk_output (pkp -> pk_chan[0]); 49141591Ssklower } 49241591Ssklower break; 49341591Ssklower 49441591Ssklower /* 49541591Ssklower * Restart confirmation received. All logical channels are set 49641591Ssklower * to READY. 49741591Ssklower */ 49841591Ssklower case RESTART_CONF + READY: 49941591Ssklower switch (pkp -> pk_state) { 50041591Ssklower case DTE_SENT_RESTART: 50141591Ssklower pkp -> pk_state = DTE_READY; 50241591Ssklower pk_message (0, pkp -> pk_xcp, 50341591Ssklower "Packet level operational"); 50441591Ssklower break; 50541591Ssklower 50641591Ssklower default: 50741591Ssklower /* Restart local procedure error. */ 50841591Ssklower pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR); 50941591Ssklower pkp -> pk_state = DTE_SENT_RESTART; 51041591Ssklower } 51141591Ssklower break; 51241591Ssklower 51341591Ssklower default: 51441591Ssklower if (lcp) { 51545895Ssklower pk_procerror (CLEAR, lcp, "unknown packet error", 33); 51641591Ssklower pk_message (lcn, pkp -> pk_xcp, 51741591Ssklower "\"%s\" unexpected in \"%s\" state", 51841591Ssklower pk_name[ptype/MAXSTATES], pk_state[lcdstate]); 51945895Ssklower } else 52045573Ssklower pk_message (lcn, pkp -> pk_xcp, 52141591Ssklower "packet arrived on unassigned lcn"); 52241591Ssklower break; 52341591Ssklower } 524*47268Ssklower if (so == 0 && lcp && lcp -> lcd_upper && 52545895Ssklower (lcdstate == SENT_CALL || lcdstate == DATA_TRANSFER)) { 52645895Ssklower if (ptype != DATA && ptype != INTERRUPT) 52745895Ssklower MCHTYPE(m, MT_CONTROL); 52845297Ssklower lcp -> lcd_upper (lcp, m); 52945895Ssklower } else if (ptype != DATA && ptype != INTERRUPT) 53041591Ssklower m_freem (m); 53141591Ssklower } 53241591Ssklower 53341591Ssklower 53441591Ssklower /* 53541591Ssklower * This routine handles incoming call packets. It matches the protocol 53641591Ssklower * field on the Call User Data field (usually the first four bytes) with 53741591Ssklower * sockets awaiting connections. 53841591Ssklower */ 53941591Ssklower 54041591Ssklower static 54145895Ssklower incoming_call (pkp, m0) 54245895Ssklower struct mbuf *m0; 54341591Ssklower struct pkcb *pkp; 54441591Ssklower { 54542277Ssklower register struct pklcd *lcp = 0, *l; 54641591Ssklower register struct sockaddr_x25 *sa; 54741591Ssklower register struct x25_calladdr *a; 54842277Ssklower register struct socket *so = 0; 54945895Ssklower struct x25_packet *xp = mtod(m0, struct x25_packet *); 55041591Ssklower struct mbuf *m; 55145895Ssklower int len = m0->m_pkthdr.len; 55241591Ssklower register int l1, l2; 55341591Ssklower char *e, *errstr = "server unavailable"; 55445895Ssklower octet *u, *facp; 55545573Ssklower int lcn = LCN(xp); 55641591Ssklower 55741591Ssklower /* First, copy the data from the incoming call packet to a X25_socket 55841591Ssklower descriptor. */ 55941591Ssklower 56041591Ssklower a = (struct x25_calladdr *) &xp -> packet_data; 56141591Ssklower l1 = a -> calling_addrlen; 56241591Ssklower l2 = a -> called_addrlen; 56345297Ssklower if ((m = m_getclr (M_DONTWAIT, MT_SONAME)) == 0) 56441591Ssklower return; 56541591Ssklower sa = mtod (m, struct sockaddr_x25 *); 56641591Ssklower u = (octet *) (a -> address_field + l2 / 2); 56741591Ssklower e = sa -> x25_addr; 56841591Ssklower if (l2 & 0x01) { 56941591Ssklower *e++ = *u++ & 0x0f; 57041591Ssklower l1--; 57141591Ssklower } 57241591Ssklower from_bcd (e, &u, l1); 57341591Ssklower if (l1 & 0x01) 57441591Ssklower u++; 57541591Ssklower 57645895Ssklower facp = u; 57741591Ssklower parse_facilities (u, sa); 57841591Ssklower u += *u + 1; 57941591Ssklower sa -> x25_udlen = min (16, ((octet *)xp) + len - u); 58041591Ssklower if (sa -> x25_udlen < 0) 58141591Ssklower sa -> x25_udlen = 0; 58241591Ssklower bcopy ((caddr_t)u, sa -> x25_udata, (unsigned)sa -> x25_udlen); 58341591Ssklower 58441591Ssklower /* 58541591Ssklower * Now, loop through the listen sockets looking for a match on the 58641591Ssklower * PID. That is the first four octets of the user data field. This 58741591Ssklower * is the closest thing to a port number for X.25 packets. What it 58841591Ssklower * does provide is away of multiplexing services at the user level. 58941591Ssklower */ 59041591Ssklower 59141591Ssklower for (l = pk_listenhead; l; l = l -> lcd_listen) { 59241591Ssklower struct sockaddr_x25 *sxp = l -> lcd_ceaddr; 59341591Ssklower 59441591Ssklower if (bcmp (sxp -> x25_udata, sa -> x25_udata, sxp->x25_udlen)) 59541591Ssklower continue; 59645165Ssklower if (sxp -> x25_net && 59745165Ssklower sxp -> x25_net != pkp->pk_xc.xc_addr.x25_net) 59841591Ssklower continue; 59941591Ssklower /* 60041591Ssklower * don't accept incoming collect calls unless 60141591Ssklower * the server sets the reverse charging option. 60241591Ssklower */ 60341591Ssklower if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 && 60441591Ssklower sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) { 60541591Ssklower errstr = "incoming collect call refused"; 60641591Ssklower break; 60741591Ssklower } 60845573Ssklower /* 60945573Ssklower * don't accept incoming calls with the D-Bit on 61045573Ssklower * unless the server agrees 61145573Ssklower */ 61245573Ssklower if (xp -> d_bit && !(sxp -> x25_opts.op_flags & X25_DBIT)) { 61345573Ssklower errstr = "incoming D-Bit mismatch"; 61445573Ssklower break; 61545573Ssklower } 61642277Ssklower if (l -> lcd_so) { 61745165Ssklower if (so = sonewconn (l -> lcd_so, SS_ISCONNECTED)) 61842277Ssklower lcp = (struct pklcd *) so -> so_pcb; 61942277Ssklower } else 62042277Ssklower lcp = pk_attach((struct socket *) 0); 62142277Ssklower if (lcp == 0) { 62241591Ssklower /* 62341591Ssklower * Insufficient space or too many unaccepted 62441591Ssklower * connections. Just throw the call away. 62541591Ssklower */ 62641591Ssklower errstr = "server malfunction"; 62741591Ssklower break; 62841591Ssklower } 62943361Ssklower lcp -> lcd_upper = l -> lcd_upper; 63043361Ssklower lcp -> lcd_upnext = l -> lcd_upnext; 63141591Ssklower lcp -> lcd_lcn = lcn; 63241591Ssklower lcp -> lcd_state = RECEIVED_CALL; 63341591Ssklower lcp -> lcd_craddr = sa; 63441591Ssklower sa -> x25_opts.op_flags |= sxp -> x25_opts.op_flags & 63541591Ssklower ~X25_REVERSE_CHARGE; 63641591Ssklower pk_assoc (pkp, lcp, sa); 63741591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED); 63845573Ssklower if (lcp -> lcd_flags & X25_DBIT) { 63945573Ssklower if (xp -> d_bit) 64045895Ssklower mtod(lcp -> lcd_template, 64145895Ssklower struct x25_packet *) -> d_bit = 1; 64245573Ssklower else 64345573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 64445573Ssklower } 64543361Ssklower if (so) { 64643361Ssklower pk_output (lcp); 64742277Ssklower soisconnected (so); 64845895Ssklower if (so -> so_options & SO_OOBINLINE) 64945895Ssklower save_extra(m0, facp, so); 65045895Ssklower } else if (lcp -> lcd_upper) { 65145895Ssklower m -> m_next = m0; 65245895Ssklower (*lcp -> lcd_upper) (lcp, m); 65345895Ssklower (void) m_free (m); /* only m; m0 freed by caller */ 65445895Ssklower } 65541591Ssklower return; 65641591Ssklower } 65741591Ssklower 65841591Ssklower /* 65941591Ssklower * If the call fails for whatever reason, we still need to build a 66041591Ssklower * skeleton LCD in order to be able to properly receive the CLEAR 66141591Ssklower * CONFIRMATION. 66241591Ssklower */ 66341591Ssklower #ifdef WATERLOO /* be explicit */ 66441591Ssklower if (l == 0 && bcmp(sa->x25_udata, "ean", 3) == 0) 66541591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s", 66641591Ssklower sa->x25_addr, sa->x25_udata[3] & 0xff, errstr); 66741591Ssklower else if (l == 0 && bcmp(sa->x25_udata, "\1\0\0\0", 4) == 0) 66841591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s", 66941591Ssklower sa->x25_addr, errstr); 67041591Ssklower else 67141591Ssklower #endif 67241591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s", 67341591Ssklower sa -> x25_addr, sa -> x25_udata[0] & 0xff, 67441591Ssklower sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff, 67541591Ssklower sa -> x25_udata[3] & 0xff, errstr); 67645297Ssklower if ((lcp = pk_attach((struct socket *)0)) == 0) { 67745297Ssklower (void) m_free (m); 67841591Ssklower return; 67941591Ssklower } 68041591Ssklower lcp -> lcd_lcn = lcn; 68141591Ssklower lcp -> lcd_state = RECEIVED_CALL; 68241591Ssklower pk_assoc (pkp, lcp, sa); 68345297Ssklower (void) m_free (m); 68445895Ssklower pk_clear (lcp, 0, 1); 68541591Ssklower } 68641591Ssklower 68741591Ssklower static 68845895Ssklower save_extra(m0, fp, so) 68945895Ssklower struct mbuf *m0; 69045895Ssklower octet *fp; 69145895Ssklower struct socket *so; 69245895Ssklower { 69345895Ssklower register struct mbuf *m; 69445895Ssklower struct cmsghdr cmsghdr; 69545895Ssklower if (m = m_copym (m, 0, (int)M_COPYALL)) { 69645895Ssklower int off = fp - mtod (m0, octet *); 69745895Ssklower int len = m->m_pkthdr.len - off + sizeof (cmsghdr); 69845895Ssklower cmsghdr.cmsg_len = len; 69945895Ssklower cmsghdr.cmsg_level = AF_CCITT; 70045895Ssklower cmsghdr.cmsg_type = PK_FACILITIES; 70145895Ssklower m_adj (m, off); 70245895Ssklower M_PREPEND (m, sizeof(cmsghdr), M_DONTWAIT); 70345895Ssklower if (m == 0) 70445895Ssklower return; 70545895Ssklower bcopy ((caddr_t)&cmsghdr, mtod (m, caddr_t), sizeof (cmsghdr)); 70645895Ssklower MCHTYPE(m, MT_CONTROL); 70745895Ssklower sbappendrecord(&so -> so_rcv, m); 70845895Ssklower } 70945895Ssklower } 71045895Ssklower 71145895Ssklower static 71241591Ssklower call_accepted (lcp, xp, len) 71341591Ssklower struct pklcd *lcp; 71441591Ssklower struct x25_packet *xp; 71541591Ssklower { 71641591Ssklower register struct x25_calladdr *ap; 71741591Ssklower register octet *fcp; 71841591Ssklower 71941591Ssklower lcp -> lcd_state = DATA_TRANSFER; 72045297Ssklower if (lcp -> lcd_so) 72145297Ssklower soisconnected (lcp -> lcd_so); 72245573Ssklower if ((lcp -> lcd_flags & X25_DBIT) && (xp -> d_bit == 0)) 72345573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 72441591Ssklower if (len > 3) { 72541591Ssklower ap = (struct x25_calladdr *) &xp -> packet_data; 72641591Ssklower fcp = (octet *) ap -> address_field + (ap -> calling_addrlen + 72741591Ssklower ap -> called_addrlen + 1) / 2; 72841591Ssklower if (fcp + *fcp <= ((octet *)xp) + len) 72941591Ssklower parse_facilities (fcp, lcp -> lcd_ceaddr); 73041591Ssklower } 73141591Ssklower pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr); 73241591Ssklower } 73341591Ssklower 73441591Ssklower static 73541591Ssklower parse_facilities (fcp, sa) 73641591Ssklower register octet *fcp; 73741591Ssklower register struct sockaddr_x25 *sa; 73841591Ssklower { 73941591Ssklower register octet *maxfcp; 74041591Ssklower 74141591Ssklower maxfcp = fcp + *fcp; 74241591Ssklower fcp++; 74341591Ssklower while (fcp < maxfcp) { 74441591Ssklower /* 74541591Ssklower * Ignore national DCE or DTE facilities 74641591Ssklower */ 74741591Ssklower if (*fcp == 0 || *fcp == 0xff) 74841591Ssklower break; 74941591Ssklower switch (*fcp) { 75041591Ssklower case FACILITIES_WINDOWSIZE: 75141591Ssklower sa -> x25_opts.op_wsize = fcp[1]; 75241591Ssklower fcp += 3; 75341591Ssklower break; 75441591Ssklower 75541591Ssklower case FACILITIES_PACKETSIZE: 75641591Ssklower sa -> x25_opts.op_psize = fcp[1]; 75741591Ssklower fcp += 3; 75841591Ssklower break; 75941591Ssklower 76041591Ssklower case FACILITIES_THROUGHPUT: 76141591Ssklower sa -> x25_opts.op_speed = fcp[1]; 76241591Ssklower fcp += 2; 76341591Ssklower break; 76441591Ssklower 76541591Ssklower case FACILITIES_REVERSE_CHARGE: 76641591Ssklower if (fcp[1] & 01) 76741591Ssklower sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE; 76841591Ssklower /* 76941591Ssklower * Datapac specific: for a X.25(1976) DTE, bit 2 77041591Ssklower * indicates a "hi priority" (eg. international) call. 77141591Ssklower */ 77241591Ssklower if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0) 77341591Ssklower sa -> x25_opts.op_psize = X25_PS128; 77441591Ssklower fcp += 2; 77541591Ssklower break; 77641591Ssklower 77741591Ssklower default: 77841591Ssklower /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/ 77941591Ssklower switch ((*fcp & 0xc0) >> 6) { 78041591Ssklower case 0: /* class A */ 78141591Ssklower fcp += 2; 78241591Ssklower break; 78341591Ssklower 78441591Ssklower case 1: 78541591Ssklower fcp += 3; 78641591Ssklower break; 78741591Ssklower 78841591Ssklower case 2: 78941591Ssklower fcp += 4; 79041591Ssklower break; 79141591Ssklower 79241591Ssklower case 3: 79341591Ssklower fcp++; 79441591Ssklower fcp += *fcp; 79541591Ssklower } 79641591Ssklower } 79741591Ssklower } 79841591Ssklower } 79941591Ssklower 80041591Ssklower from_bcd (a, x, len) 80141591Ssklower register char *a; 80241591Ssklower register octet **x; 80341591Ssklower register int len; 80441591Ssklower { 80541591Ssklower register int posn = 0; 80641591Ssklower 80741591Ssklower while (--len >= 0) { 80841591Ssklower if (posn++ & 0x01) 80941591Ssklower *a = *(*x)++ & 0x0f; 81041591Ssklower else 81141591Ssklower *a = (**x >> 4) & 0x0F; 81241591Ssklower *a++ |= 0x30; 81341591Ssklower } 81441591Ssklower } 815