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*45573Ssklower * @(#)pk_input.c 7.7 (Berkeley) 11/13/90 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); 143*45573Ssklower 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 15741591Ssklower pk_trace (pkp -> pk_xcp, xp, "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: 19241591Ssklower incoming_call (pkp, xp, m -> m_len); 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: 200*45573Ssklower 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); 27941591Ssklower pk_procerror (RESET, lcp, "p(s) flow control error"); 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 } 28845297Ssklower if (so == 0) 28945297Ssklower break; 29043361Ssklower m -> m_data += PKHEADERLN; 29141591Ssklower m -> m_len -= PKHEADERLN; 29241591Ssklower if (lcp -> lcd_flags & X25_MQBIT) { 293*45573Ssklower octet t = (xp -> q_bit) ? t = 0x80 : 0; 29441591Ssklower 295*45573Ssklower if (MBIT(xp)) 296*45573Ssklower t |= 0x40; 29743361Ssklower m -> m_data -= 1; 29841591Ssklower m -> m_len += 1; 299*45573Ssklower *mtod(m, octet *) = t; 30041591Ssklower } 30141591Ssklower 30241591Ssklower /* 30341591Ssklower * Discard Q-BIT packets if the application 30441591Ssklower * doesn't want to be informed of M and Q bit status 30541591Ssklower */ 30641591Ssklower if (xp -> q_bit && (lcp -> lcd_flags & X25_MQBIT) == 0) { 30741591Ssklower m_freem (m); 30841591Ssklower lcp -> lcd_rxcnt++; 30941591Ssklower /* 31041591Ssklower * NB. This is dangerous: sending a RR here can 31141591Ssklower * cause sequence number errors if a previous data 31241591Ssklower * packet has not yet been passed up to the application 31341591Ssklower * (RR's are normally generated via PRU_RCVD). 31441591Ssklower */ 31541591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RR); 31641591Ssklower pk_output (lcp); 31741591Ssklower } else { 31841591Ssklower sbappendrecord (&so -> so_rcv, m); 31941591Ssklower sorwakeup (so); 32041591Ssklower } 32141591Ssklower break; 32241591Ssklower 32341591Ssklower /* 32441591Ssklower * Interrupt packet received. 32541591Ssklower */ 32641591Ssklower case INTERRUPT + DATA_TRANSFER: 32741591Ssklower if (lcp -> lcd_reset_condition) 32841591Ssklower break; 32941591Ssklower lcp -> lcd_intrdata = xp -> packet_data; 33041591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM); 33141591Ssklower pk_output (lcp); 33245297Ssklower MCHTYPE(m, MT_OOBDATA); 33345297Ssklower if (so) 33445297Ssklower sohasoutofband (so); 33541591Ssklower break; 33641591Ssklower 33741591Ssklower /* 33841591Ssklower * Interrupt confirmation packet received. 33941591Ssklower */ 34041591Ssklower case INTERRUPT_CONF + DATA_TRANSFER: 34141591Ssklower if (lcp -> lcd_reset_condition) 34241591Ssklower break; 34341591Ssklower if (lcp -> lcd_intrconf_pending == TRUE) 34441591Ssklower lcp -> lcd_intrconf_pending = FALSE; 34541591Ssklower else 34641591Ssklower pk_procerror (RESET, lcp, "unexpected packet"); 34745297Ssklower MCHTYPE(m, MT_CONTROL); 34841591Ssklower break; 34941591Ssklower 35041591Ssklower /* 35141591Ssklower * Receiver ready received. Rotate the output window and output 35241591Ssklower * any data packets waiting transmission. 35341591Ssklower */ 35441591Ssklower case RR + DATA_TRANSFER: 35545297Ssklower if (lcp -> lcd_reset_condition || 35645297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 35745297Ssklower ptype = DELETE_PACKET; 35841591Ssklower break; 35945297Ssklower } 36041591Ssklower if (lcp -> lcd_rnr_condition == TRUE) 36141591Ssklower lcp -> lcd_rnr_condition = FALSE; 36241591Ssklower pk_output (lcp); 36345297Ssklower MCHTYPE(m, MT_CONTROL); 36441591Ssklower break; 36541591Ssklower 36641591Ssklower /* 36741591Ssklower * Receiver Not Ready received. Packets up to the P(R) can be 36841591Ssklower * be sent. Condition is cleared with a RR. 36941591Ssklower */ 37041591Ssklower case RNR + DATA_TRANSFER: 37145297Ssklower if (lcp -> lcd_reset_condition || 37245297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 37345297Ssklower ptype = DELETE_PACKET; 37441591Ssklower break; 37545297Ssklower } 37641591Ssklower lcp -> lcd_rnr_condition = TRUE; 37745297Ssklower MCHTYPE(m, MT_CONTROL); 37841591Ssklower break; 37941591Ssklower 38041591Ssklower /* 38141591Ssklower * Reset packet received. Set state to FLOW_OPEN. The Input and 38241591Ssklower * Output window edges ar set to zero. Both the send and receive 38341591Ssklower * numbers are reset. A confirmation is returned. 38441591Ssklower */ 38541591Ssklower case RESET + DATA_TRANSFER: 38641591Ssklower if (lcp -> lcd_reset_condition) 38741591Ssklower /* Reset collision. Just ignore packet. */ 38841591Ssklower break; 38941591Ssklower 39041591Ssklower pk_resetcause (pkp, xp); 39141591Ssklower lcp -> lcd_window_condition = lcp -> lcd_rnr_condition = 39241591Ssklower lcp -> lcd_intrconf_pending = FALSE; 39341591Ssklower lcp -> lcd_output_window = lcp -> lcd_input_window = 39441591Ssklower lcp -> lcd_last_transmitted_pr = 0; 39541591Ssklower lcp -> lcd_ssn = 0; 39641591Ssklower lcp -> lcd_rsn = MODULUS - 1; 39741591Ssklower 39841591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM); 39941591Ssklower pk_output (lcp); 40045297Ssklower 40145297Ssklower MCHTYPE(m, MT_CONTROL); 40245297Ssklower if (so == 0) 40345297Ssklower break; 40445297Ssklower sbflush (&so -> so_snd); 40545297Ssklower sbflush (&so -> so_rcv); 40645297Ssklower wakeup ((caddr_t) & so -> so_timeo); 40745297Ssklower sorwakeup (so); 40845297Ssklower sowwakeup (so); 40941591Ssklower break; 41041591Ssklower 41141591Ssklower /* 41241591Ssklower * Reset confirmation received. 41341591Ssklower */ 41441591Ssklower case RESET_CONF + DATA_TRANSFER: 41541591Ssklower if (lcp -> lcd_reset_condition) { 41641591Ssklower lcp -> lcd_reset_condition = FALSE; 41741591Ssklower pk_output (lcp); 41841591Ssklower } 41941591Ssklower else 42041591Ssklower pk_procerror (RESET, lcp, "unexpected packet"); 42145297Ssklower MCHTYPE(m, MT_CONTROL); 42241591Ssklower break; 42341591Ssklower 42441591Ssklower case DATA + SENT_CLEAR: 42541591Ssklower ptype = DELETE_PACKET; 42641591Ssklower case RR + SENT_CLEAR: 42741591Ssklower case RNR + SENT_CLEAR: 42841591Ssklower case INTERRUPT + SENT_CLEAR: 42941591Ssklower case INTERRUPT_CONF + SENT_CLEAR: 43041591Ssklower case RESET + SENT_CLEAR: 43141591Ssklower case RESET_CONF + SENT_CLEAR: 43245297Ssklower /* Just ignore p if we have sent a CLEAR already. 43341591Ssklower */ 43441591Ssklower break; 43541591Ssklower 43641591Ssklower /* 43741591Ssklower * Restart sets all the permanent virtual circuits to the "Data 43841591Ssklower * Transfer" stae and all the switched virtual circuits to the 43941591Ssklower * "Ready" state. 44041591Ssklower */ 44141591Ssklower case RESTART + READY: 44241591Ssklower switch (pkp -> pk_state) { 44341591Ssklower case DTE_SENT_RESTART: 44441591Ssklower /* Restart collision. */ 44541591Ssklower pkp -> pk_state = DTE_READY; 44641591Ssklower pk_message (0, pkp -> pk_xcp, 44741591Ssklower "Packet level operational"); 44841591Ssklower break; 44941591Ssklower 45041591Ssklower default: 45141591Ssklower pk_restart (pkp, -1); 45241591Ssklower pk_restartcause (pkp, xp); 45341591Ssklower pkp -> pk_chan[0] -> lcd_template = pk_template (0, 45441591Ssklower X25_RESTART_CONFIRM); 45541591Ssklower pk_output (pkp -> pk_chan[0]); 45641591Ssklower } 45741591Ssklower break; 45841591Ssklower 45941591Ssklower /* 46041591Ssklower * Restart confirmation received. All logical channels are set 46141591Ssklower * to READY. 46241591Ssklower */ 46341591Ssklower case RESTART_CONF + READY: 46441591Ssklower switch (pkp -> pk_state) { 46541591Ssklower case DTE_SENT_RESTART: 46641591Ssklower pkp -> pk_state = DTE_READY; 46741591Ssklower pk_message (0, pkp -> pk_xcp, 46841591Ssklower "Packet level operational"); 46941591Ssklower break; 47041591Ssklower 47141591Ssklower default: 47241591Ssklower /* Restart local procedure error. */ 47341591Ssklower pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR); 47441591Ssklower pkp -> pk_state = DTE_SENT_RESTART; 47541591Ssklower } 47641591Ssklower break; 47741591Ssklower 47841591Ssklower default: 47941591Ssklower if (lcp) { 48041591Ssklower pk_procerror (CLEAR, lcp, "unknown packet error"); 48141591Ssklower pk_message (lcn, pkp -> pk_xcp, 48241591Ssklower "\"%s\" unexpected in \"%s\" state", 48341591Ssklower pk_name[ptype/MAXSTATES], pk_state[lcdstate]); 48441591Ssklower } 48541591Ssklower else /* Packets arrived on an unassigned channel. 48641591Ssklower */ 487*45573Ssklower pk_message (lcn, pkp -> pk_xcp, 48841591Ssklower "packet arrived on unassigned lcn"); 48941591Ssklower break; 49041591Ssklower } 49145297Ssklower if (so == 0 && lcdstate == DATA_TRANSFER && lcp -> lcd_upper) 49245297Ssklower lcp -> lcd_upper (lcp, m); 49345297Ssklower else if (ptype != DATA) 49441591Ssklower m_freem (m); 49541591Ssklower } 49641591Ssklower 49741591Ssklower 49841591Ssklower /* 49941591Ssklower * This routine handles incoming call packets. It matches the protocol 50041591Ssklower * field on the Call User Data field (usually the first four bytes) with 50141591Ssklower * sockets awaiting connections. 50241591Ssklower */ 50341591Ssklower 50441591Ssklower static 50541591Ssklower incoming_call (pkp, xp, len) 50641591Ssklower struct pkcb *pkp; 50741591Ssklower struct x25_packet *xp; 50841591Ssklower { 50942277Ssklower register struct pklcd *lcp = 0, *l; 51041591Ssklower register struct sockaddr_x25 *sa; 51141591Ssklower register struct x25_calladdr *a; 51242277Ssklower register struct socket *so = 0; 51341591Ssklower struct mbuf *m; 51441591Ssklower register int l1, l2; 51541591Ssklower char *e, *errstr = "server unavailable"; 51641591Ssklower octet *u; 517*45573Ssklower int lcn = LCN(xp); 51841591Ssklower 51941591Ssklower /* First, copy the data from the incoming call packet to a X25_socket 52041591Ssklower descriptor. */ 52141591Ssklower 52241591Ssklower a = (struct x25_calladdr *) &xp -> packet_data; 52341591Ssklower l1 = a -> calling_addrlen; 52441591Ssklower l2 = a -> called_addrlen; 52545297Ssklower if ((m = m_getclr (M_DONTWAIT, MT_SONAME)) == 0) 52641591Ssklower return; 52741591Ssklower sa = mtod (m, struct sockaddr_x25 *); 52841591Ssklower u = (octet *) (a -> address_field + l2 / 2); 52941591Ssklower e = sa -> x25_addr; 53041591Ssklower if (l2 & 0x01) { 53141591Ssklower *e++ = *u++ & 0x0f; 53241591Ssklower l1--; 53341591Ssklower } 53441591Ssklower from_bcd (e, &u, l1); 53541591Ssklower if (l1 & 0x01) 53641591Ssklower u++; 53741591Ssklower 53841591Ssklower parse_facilities (u, sa); 53941591Ssklower u += *u + 1; 54041591Ssklower sa -> x25_udlen = min (16, ((octet *)xp) + len - u); 54141591Ssklower if (sa -> x25_udlen < 0) 54241591Ssklower sa -> x25_udlen = 0; 54341591Ssklower bcopy ((caddr_t)u, sa -> x25_udata, (unsigned)sa -> x25_udlen); 54441591Ssklower 54541591Ssklower /* 54641591Ssklower * Now, loop through the listen sockets looking for a match on the 54741591Ssklower * PID. That is the first four octets of the user data field. This 54841591Ssklower * is the closest thing to a port number for X.25 packets. What it 54941591Ssklower * does provide is away of multiplexing services at the user level. 55041591Ssklower */ 55141591Ssklower 55241591Ssklower for (l = pk_listenhead; l; l = l -> lcd_listen) { 55341591Ssklower struct sockaddr_x25 *sxp = l -> lcd_ceaddr; 55441591Ssklower 55541591Ssklower if (bcmp (sxp -> x25_udata, sa -> x25_udata, sxp->x25_udlen)) 55641591Ssklower continue; 55745165Ssklower if (sxp -> x25_net && 55845165Ssklower sxp -> x25_net != pkp->pk_xc.xc_addr.x25_net) 55941591Ssklower continue; 56041591Ssklower /* 56141591Ssklower * don't accept incoming collect calls unless 56241591Ssklower * the server sets the reverse charging option. 56341591Ssklower */ 56441591Ssklower if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 && 56541591Ssklower sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) { 56641591Ssklower errstr = "incoming collect call refused"; 56741591Ssklower break; 56841591Ssklower } 569*45573Ssklower /* 570*45573Ssklower * don't accept incoming calls with the D-Bit on 571*45573Ssklower * unless the server agrees 572*45573Ssklower */ 573*45573Ssklower if (xp -> d_bit && !(sxp -> x25_opts.op_flags & X25_DBIT)) { 574*45573Ssklower errstr = "incoming D-Bit mismatch"; 575*45573Ssklower break; 576*45573Ssklower } 57742277Ssklower if (l -> lcd_so) { 57845165Ssklower if (so = sonewconn (l -> lcd_so, SS_ISCONNECTED)) 57942277Ssklower lcp = (struct pklcd *) so -> so_pcb; 58042277Ssklower } else 58142277Ssklower lcp = pk_attach((struct socket *) 0); 58242277Ssklower if (lcp == 0) { 58341591Ssklower /* 58441591Ssklower * Insufficient space or too many unaccepted 58541591Ssklower * connections. Just throw the call away. 58641591Ssklower */ 58741591Ssklower errstr = "server malfunction"; 58841591Ssklower break; 58941591Ssklower } 59043361Ssklower lcp -> lcd_upper = l -> lcd_upper; 59143361Ssklower lcp -> lcd_upnext = l -> lcd_upnext; 59241591Ssklower lcp -> lcd_lcn = lcn; 59341591Ssklower lcp -> lcd_state = RECEIVED_CALL; 59441591Ssklower lcp -> lcd_craddr = sa; 59541591Ssklower sa -> x25_opts.op_flags |= sxp -> x25_opts.op_flags & 59641591Ssklower ~X25_REVERSE_CHARGE; 59741591Ssklower pk_assoc (pkp, lcp, sa); 59841591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED); 599*45573Ssklower if (lcp -> lcd_flags & X25_DBIT) { 600*45573Ssklower if (xp -> d_bit) 601*45573Ssklower lcp -> lcd_template -> d_bit = 1; 602*45573Ssklower else 603*45573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 604*45573Ssklower } 60543361Ssklower if (so) { 60643361Ssklower pk_output (lcp); 60742277Ssklower soisconnected (so); 60843361Ssklower } else if (lcp->lcd_upper) 60945297Ssklower (*lcp->lcd_upper)(lcp, m); 61041591Ssklower return; 61141591Ssklower } 61241591Ssklower 61341591Ssklower /* 61441591Ssklower * If the call fails for whatever reason, we still need to build a 61541591Ssklower * skeleton LCD in order to be able to properly receive the CLEAR 61641591Ssklower * CONFIRMATION. 61741591Ssklower */ 61841591Ssklower #ifdef WATERLOO /* be explicit */ 61941591Ssklower if (l == 0 && bcmp(sa->x25_udata, "ean", 3) == 0) 62041591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s", 62141591Ssklower sa->x25_addr, sa->x25_udata[3] & 0xff, errstr); 62241591Ssklower else if (l == 0 && bcmp(sa->x25_udata, "\1\0\0\0", 4) == 0) 62341591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s", 62441591Ssklower sa->x25_addr, errstr); 62541591Ssklower else 62641591Ssklower #endif 62741591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s", 62841591Ssklower sa -> x25_addr, sa -> x25_udata[0] & 0xff, 62941591Ssklower sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff, 63041591Ssklower sa -> x25_udata[3] & 0xff, errstr); 63145297Ssklower if ((lcp = pk_attach((struct socket *)0)) == 0) { 63245297Ssklower (void) m_free (m); 63341591Ssklower return; 63441591Ssklower } 63541591Ssklower lcp -> lcd_lcn = lcn; 63641591Ssklower lcp -> lcd_state = RECEIVED_CALL; 63741591Ssklower pk_assoc (pkp, lcp, sa); 63845297Ssklower (void) m_free (m); 63941591Ssklower pk_clear (lcp); 64041591Ssklower } 64141591Ssklower 64241591Ssklower static 64341591Ssklower call_accepted (lcp, xp, len) 64441591Ssklower struct pklcd *lcp; 64541591Ssklower struct x25_packet *xp; 64641591Ssklower { 64741591Ssklower register struct x25_calladdr *ap; 64841591Ssklower register octet *fcp; 64941591Ssklower 65041591Ssklower lcp -> lcd_state = DATA_TRANSFER; 65145297Ssklower if (lcp -> lcd_so) 65245297Ssklower soisconnected (lcp -> lcd_so); 653*45573Ssklower if ((lcp -> lcd_flags & X25_DBIT) && (xp -> d_bit == 0)) 654*45573Ssklower lcp -> lcd_flags &= ~X25_DBIT; 65541591Ssklower if (len > 3) { 65641591Ssklower ap = (struct x25_calladdr *) &xp -> packet_data; 65741591Ssklower fcp = (octet *) ap -> address_field + (ap -> calling_addrlen + 65841591Ssklower ap -> called_addrlen + 1) / 2; 65941591Ssklower if (fcp + *fcp <= ((octet *)xp) + len) 66041591Ssklower parse_facilities (fcp, lcp -> lcd_ceaddr); 66141591Ssklower } 66241591Ssklower pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr); 66341591Ssklower } 66441591Ssklower 66541591Ssklower static 66641591Ssklower parse_facilities (fcp, sa) 66741591Ssklower register octet *fcp; 66841591Ssklower register struct sockaddr_x25 *sa; 66941591Ssklower { 67041591Ssklower register octet *maxfcp; 67141591Ssklower 67241591Ssklower maxfcp = fcp + *fcp; 67341591Ssklower fcp++; 67441591Ssklower while (fcp < maxfcp) { 67541591Ssklower /* 67641591Ssklower * Ignore national DCE or DTE facilities 67741591Ssklower */ 67841591Ssklower if (*fcp == 0 || *fcp == 0xff) 67941591Ssklower break; 68041591Ssklower switch (*fcp) { 68141591Ssklower case FACILITIES_WINDOWSIZE: 68241591Ssklower sa -> x25_opts.op_wsize = fcp[1]; 68341591Ssklower fcp += 3; 68441591Ssklower break; 68541591Ssklower 68641591Ssklower case FACILITIES_PACKETSIZE: 68741591Ssklower sa -> x25_opts.op_psize = fcp[1]; 68841591Ssklower fcp += 3; 68941591Ssklower break; 69041591Ssklower 69141591Ssklower case FACILITIES_THROUGHPUT: 69241591Ssklower sa -> x25_opts.op_speed = fcp[1]; 69341591Ssklower fcp += 2; 69441591Ssklower break; 69541591Ssklower 69641591Ssklower case FACILITIES_REVERSE_CHARGE: 69741591Ssklower if (fcp[1] & 01) 69841591Ssklower sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE; 69941591Ssklower /* 70041591Ssklower * Datapac specific: for a X.25(1976) DTE, bit 2 70141591Ssklower * indicates a "hi priority" (eg. international) call. 70241591Ssklower */ 70341591Ssklower if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0) 70441591Ssklower sa -> x25_opts.op_psize = X25_PS128; 70541591Ssklower fcp += 2; 70641591Ssklower break; 70741591Ssklower 70841591Ssklower default: 70941591Ssklower /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/ 71041591Ssklower switch ((*fcp & 0xc0) >> 6) { 71141591Ssklower case 0: /* class A */ 71241591Ssklower fcp += 2; 71341591Ssklower break; 71441591Ssklower 71541591Ssklower case 1: 71641591Ssklower fcp += 3; 71741591Ssklower break; 71841591Ssklower 71941591Ssklower case 2: 72041591Ssklower fcp += 4; 72141591Ssklower break; 72241591Ssklower 72341591Ssklower case 3: 72441591Ssklower fcp++; 72541591Ssklower fcp += *fcp; 72641591Ssklower } 72741591Ssklower } 72841591Ssklower } 72941591Ssklower } 73041591Ssklower 73141591Ssklower from_bcd (a, x, len) 73241591Ssklower register char *a; 73341591Ssklower register octet **x; 73441591Ssklower register int len; 73541591Ssklower { 73641591Ssklower register int posn = 0; 73741591Ssklower 73841591Ssklower while (--len >= 0) { 73941591Ssklower if (posn++ & 0x01) 74041591Ssklower *a = *(*x)++ & 0x0f; 74141591Ssklower else 74241591Ssklower *a = (**x >> 4) & 0x0F; 74341591Ssklower *a++ |= 0x30; 74441591Ssklower } 74541591Ssklower } 746