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*45297Ssklower * @(#)pk_input.c 7.6 (Berkeley) 10/04/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 34*45297Ssklower pk_ctlinput (code, xcp) 35*45297Ssklower register struct x25config *xcp; 3641591Ssklower { 3741591Ssklower 38*45297Ssklower register struct pkcb *pkp; 39*45297Ssklower 40*45297Ssklower for (pkp = pkcbhead; pkp; pkp = pkp -> pk_next) 41*45297Ssklower if (pkp -> pk_xcp == xcp) 42*45297Ssklower break; 43*45297Ssklower 4442277Ssklower if (pkp == 0) 4541591Ssklower return (EINVAL); 46*45297Ssklower 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 } 65*45297Ssklower struct ifqueue pkintrq; 66*45297Ssklower /* 67*45297Ssklower * This routine is called if there are semi-smart devices that do HDLC 68*45297Ssklower * in hardware and want to queue the packet and call level 3 directly 69*45297Ssklower */ 70*45297Ssklower pkintr () 71*45297Ssklower { 72*45297Ssklower register struct mbuf *m; 73*45297Ssklower register struct ifaddr *ifa; 74*45297Ssklower register struct ifnet *ifp; 75*45297Ssklower register int s; 7641591Ssklower 77*45297Ssklower for (;;) { 78*45297Ssklower s = splimp (); 79*45297Ssklower IF_DEQUEUE (&pkintrq, m); 80*45297Ssklower splx (s); 81*45297Ssklower if (m == 0) 82*45297Ssklower break; 83*45297Ssklower if (m->m_len < PKHEADERLN) { 84*45297Ssklower printf ("pkintr: packet too short (len=%d)\n", 85*45297Ssklower m->m_len); 86*45297Ssklower m_freem (m); 87*45297Ssklower continue; 88*45297Ssklower } 89*45297Ssklower if ((m->m_flags & M_PKTHDR) == 0) 90*45297Ssklower panic("pkintr"); 91*45297Ssklower ifp = m->m_pkthdr.rcvif; 92*45297Ssklower /* 93*45297Ssklower * look up the appropriate control block 94*45297Ssklower */ 95*45297Ssklower for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) 96*45297Ssklower if (ifa->ifa_addr->sa_family == AF_CCITT) 97*45297Ssklower break; 98*45297Ssklower if (ifa == 0) 99*45297Ssklower continue; 100*45297Ssklower pk_input(m, ((struct x25_ifaddr *)ifa)->ia_xcp); 101*45297Ssklower } 102*45297Ssklower } 103*45297Ssklower 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); 14341591Ssklower lcn = xp -> logical_channel_number; 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) { 179*45297Ssklower pk_message (0, pkp -> pk_xcp, "illegal ptype (%d, %s) on lcn 0", 180*45297Ssklower ptype, pk_name[ptype / MAXSTATES]); 181*45297Ssklower if (pk_bad_packet) 182*45297Ssklower m_freem (pk_bad_packet); 183*45297Ssklower 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: 20041591Ssklower pk_message ((int)xp -> logical_channel_number, 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 } 288*45297Ssklower if (so == 0) 289*45297Ssklower break; 29043361Ssklower m -> m_data += PKHEADERLN; 29141591Ssklower m -> m_len -= PKHEADERLN; 29241591Ssklower if (lcp -> lcd_flags & X25_MQBIT) { 29341591Ssklower octet *t; 29441591Ssklower 29543361Ssklower m -> m_data -= 1; 29641591Ssklower m -> m_len += 1; 29741591Ssklower t = mtod (m, octet *); 29841591Ssklower *t = 0x00; 29941591Ssklower if (xp -> q_bit) 30041591Ssklower *t |= 0x80; 30141591Ssklower if (MBIT(xp)) 30241591Ssklower *t |= 0x40; 30341591Ssklower } 30441591Ssklower 30541591Ssklower /* 30641591Ssklower * Discard Q-BIT packets if the application 30741591Ssklower * doesn't want to be informed of M and Q bit status 30841591Ssklower */ 30941591Ssklower if (xp -> q_bit && (lcp -> lcd_flags & X25_MQBIT) == 0) { 31041591Ssklower m_freem (m); 31141591Ssklower lcp -> lcd_rxcnt++; 31241591Ssklower /* 31341591Ssklower * NB. This is dangerous: sending a RR here can 31441591Ssklower * cause sequence number errors if a previous data 31541591Ssklower * packet has not yet been passed up to the application 31641591Ssklower * (RR's are normally generated via PRU_RCVD). 31741591Ssklower */ 31841591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RR); 31941591Ssklower pk_output (lcp); 32041591Ssklower } else { 32141591Ssklower #ifdef BSD4_3 32241591Ssklower sbappendrecord (&so -> so_rcv, m); 32341591Ssklower #else 32441591Ssklower sbappend (&so -> so_rcv, m); 32541591Ssklower #endif 32641591Ssklower sorwakeup (so); 32741591Ssklower } 32841591Ssklower break; 32941591Ssklower 33041591Ssklower /* 33141591Ssklower * Interrupt packet received. 33241591Ssklower */ 33341591Ssklower case INTERRUPT + DATA_TRANSFER: 33441591Ssklower if (lcp -> lcd_reset_condition) 33541591Ssklower break; 33641591Ssklower lcp -> lcd_intrdata = xp -> packet_data; 33741591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM); 33841591Ssklower pk_output (lcp); 339*45297Ssklower MCHTYPE(m, MT_OOBDATA); 340*45297Ssklower if (so) 341*45297Ssklower sohasoutofband (so); 34241591Ssklower break; 34341591Ssklower 34441591Ssklower /* 34541591Ssklower * Interrupt confirmation packet received. 34641591Ssklower */ 34741591Ssklower case INTERRUPT_CONF + DATA_TRANSFER: 34841591Ssklower if (lcp -> lcd_reset_condition) 34941591Ssklower break; 35041591Ssklower if (lcp -> lcd_intrconf_pending == TRUE) 35141591Ssklower lcp -> lcd_intrconf_pending = FALSE; 35241591Ssklower else 35341591Ssklower pk_procerror (RESET, lcp, "unexpected packet"); 354*45297Ssklower MCHTYPE(m, MT_CONTROL); 35541591Ssklower break; 35641591Ssklower 35741591Ssklower /* 35841591Ssklower * Receiver ready received. Rotate the output window and output 35941591Ssklower * any data packets waiting transmission. 36041591Ssklower */ 36141591Ssklower case RR + DATA_TRANSFER: 362*45297Ssklower if (lcp -> lcd_reset_condition || 363*45297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 364*45297Ssklower ptype = DELETE_PACKET; 36541591Ssklower break; 366*45297Ssklower } 36741591Ssklower if (lcp -> lcd_rnr_condition == TRUE) 36841591Ssklower lcp -> lcd_rnr_condition = FALSE; 36941591Ssklower pk_output (lcp); 370*45297Ssklower MCHTYPE(m, MT_CONTROL); 37141591Ssklower break; 37241591Ssklower 37341591Ssklower /* 37441591Ssklower * Receiver Not Ready received. Packets up to the P(R) can be 37541591Ssklower * be sent. Condition is cleared with a RR. 37641591Ssklower */ 37741591Ssklower case RNR + DATA_TRANSFER: 378*45297Ssklower if (lcp -> lcd_reset_condition || 379*45297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) { 380*45297Ssklower ptype = DELETE_PACKET; 38141591Ssklower break; 382*45297Ssklower } 38341591Ssklower lcp -> lcd_rnr_condition = TRUE; 384*45297Ssklower MCHTYPE(m, MT_CONTROL); 38541591Ssklower break; 38641591Ssklower 38741591Ssklower /* 38841591Ssklower * Reset packet received. Set state to FLOW_OPEN. The Input and 38941591Ssklower * Output window edges ar set to zero. Both the send and receive 39041591Ssklower * numbers are reset. A confirmation is returned. 39141591Ssklower */ 39241591Ssklower case RESET + DATA_TRANSFER: 39341591Ssklower if (lcp -> lcd_reset_condition) 39441591Ssklower /* Reset collision. Just ignore packet. */ 39541591Ssklower break; 39641591Ssklower 39741591Ssklower pk_resetcause (pkp, xp); 39841591Ssklower lcp -> lcd_window_condition = lcp -> lcd_rnr_condition = 39941591Ssklower lcp -> lcd_intrconf_pending = FALSE; 40041591Ssklower lcp -> lcd_output_window = lcp -> lcd_input_window = 40141591Ssklower lcp -> lcd_last_transmitted_pr = 0; 40241591Ssklower lcp -> lcd_ssn = 0; 40341591Ssklower lcp -> lcd_rsn = MODULUS - 1; 40441591Ssklower 40541591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM); 40641591Ssklower pk_output (lcp); 407*45297Ssklower 408*45297Ssklower MCHTYPE(m, MT_CONTROL); 409*45297Ssklower if (so == 0) 410*45297Ssklower break; 411*45297Ssklower sbflush (&so -> so_snd); 412*45297Ssklower sbflush (&so -> so_rcv); 413*45297Ssklower wakeup ((caddr_t) & so -> so_timeo); 414*45297Ssklower sorwakeup (so); 415*45297Ssklower sowwakeup (so); 41641591Ssklower break; 41741591Ssklower 41841591Ssklower /* 41941591Ssklower * Reset confirmation received. 42041591Ssklower */ 42141591Ssklower case RESET_CONF + DATA_TRANSFER: 42241591Ssklower if (lcp -> lcd_reset_condition) { 42341591Ssklower lcp -> lcd_reset_condition = FALSE; 42441591Ssklower pk_output (lcp); 42541591Ssklower } 42641591Ssklower else 42741591Ssklower pk_procerror (RESET, lcp, "unexpected packet"); 428*45297Ssklower MCHTYPE(m, MT_CONTROL); 42941591Ssklower break; 43041591Ssklower 43141591Ssklower case DATA + SENT_CLEAR: 43241591Ssklower ptype = DELETE_PACKET; 43341591Ssklower case RR + SENT_CLEAR: 43441591Ssklower case RNR + SENT_CLEAR: 43541591Ssklower case INTERRUPT + SENT_CLEAR: 43641591Ssklower case INTERRUPT_CONF + SENT_CLEAR: 43741591Ssklower case RESET + SENT_CLEAR: 43841591Ssklower case RESET_CONF + SENT_CLEAR: 439*45297Ssklower /* Just ignore p if we have sent a CLEAR already. 44041591Ssklower */ 44141591Ssklower break; 44241591Ssklower 44341591Ssklower /* 44441591Ssklower * Restart sets all the permanent virtual circuits to the "Data 44541591Ssklower * Transfer" stae and all the switched virtual circuits to the 44641591Ssklower * "Ready" state. 44741591Ssklower */ 44841591Ssklower case RESTART + READY: 44941591Ssklower switch (pkp -> pk_state) { 45041591Ssklower case DTE_SENT_RESTART: 45141591Ssklower /* Restart collision. */ 45241591Ssklower pkp -> pk_state = DTE_READY; 45341591Ssklower pk_message (0, pkp -> pk_xcp, 45441591Ssklower "Packet level operational"); 45541591Ssklower break; 45641591Ssklower 45741591Ssklower default: 45841591Ssklower pk_restart (pkp, -1); 45941591Ssklower pk_restartcause (pkp, xp); 46041591Ssklower pkp -> pk_chan[0] -> lcd_template = pk_template (0, 46141591Ssklower X25_RESTART_CONFIRM); 46241591Ssklower pk_output (pkp -> pk_chan[0]); 46341591Ssklower } 46441591Ssklower break; 46541591Ssklower 46641591Ssklower /* 46741591Ssklower * Restart confirmation received. All logical channels are set 46841591Ssklower * to READY. 46941591Ssklower */ 47041591Ssklower case RESTART_CONF + READY: 47141591Ssklower switch (pkp -> pk_state) { 47241591Ssklower case DTE_SENT_RESTART: 47341591Ssklower pkp -> pk_state = DTE_READY; 47441591Ssklower pk_message (0, pkp -> pk_xcp, 47541591Ssklower "Packet level operational"); 47641591Ssklower break; 47741591Ssklower 47841591Ssklower default: 47941591Ssklower /* Restart local procedure error. */ 48041591Ssklower pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR); 48141591Ssklower pkp -> pk_state = DTE_SENT_RESTART; 48241591Ssklower } 48341591Ssklower break; 48441591Ssklower 48541591Ssklower default: 48641591Ssklower if (lcp) { 48741591Ssklower pk_procerror (CLEAR, lcp, "unknown packet error"); 48841591Ssklower pk_message (lcn, pkp -> pk_xcp, 48941591Ssklower "\"%s\" unexpected in \"%s\" state", 49041591Ssklower pk_name[ptype/MAXSTATES], pk_state[lcdstate]); 49141591Ssklower } 49241591Ssklower else /* Packets arrived on an unassigned channel. 49341591Ssklower */ 49441591Ssklower pk_message ((int)xp->logical_channel_number, pkp -> pk_xcp, 49541591Ssklower "packet arrived on unassigned lcn"); 49641591Ssklower break; 49741591Ssklower } 498*45297Ssklower if (so == 0 && lcdstate == DATA_TRANSFER && lcp -> lcd_upper) 499*45297Ssklower lcp -> lcd_upper (lcp, m); 500*45297Ssklower else if (ptype != DATA) 50141591Ssklower m_freem (m); 50241591Ssklower } 50341591Ssklower 50441591Ssklower 50541591Ssklower /* 50641591Ssklower * This routine handles incoming call packets. It matches the protocol 50741591Ssklower * field on the Call User Data field (usually the first four bytes) with 50841591Ssklower * sockets awaiting connections. 50941591Ssklower */ 51041591Ssklower 51141591Ssklower static 51241591Ssklower incoming_call (pkp, xp, len) 51341591Ssklower struct pkcb *pkp; 51441591Ssklower struct x25_packet *xp; 51541591Ssklower { 51642277Ssklower register struct pklcd *lcp = 0, *l; 51741591Ssklower register struct sockaddr_x25 *sa; 51841591Ssklower register struct x25_calladdr *a; 51942277Ssklower register struct socket *so = 0; 52041591Ssklower struct mbuf *m; 52141591Ssklower register int l1, l2; 52241591Ssklower char *e, *errstr = "server unavailable"; 52341591Ssklower octet *u; 52441591Ssklower int lcn = xp -> logical_channel_number; 52541591Ssklower 52641591Ssklower /* First, copy the data from the incoming call packet to a X25_socket 52741591Ssklower descriptor. */ 52841591Ssklower 52941591Ssklower a = (struct x25_calladdr *) &xp -> packet_data; 53041591Ssklower l1 = a -> calling_addrlen; 53141591Ssklower l2 = a -> called_addrlen; 532*45297Ssklower if ((m = m_getclr (M_DONTWAIT, MT_SONAME)) == 0) 53341591Ssklower return; 53441591Ssklower sa = mtod (m, struct sockaddr_x25 *); 53541591Ssklower u = (octet *) (a -> address_field + l2 / 2); 53641591Ssklower e = sa -> x25_addr; 53741591Ssklower if (l2 & 0x01) { 53841591Ssklower *e++ = *u++ & 0x0f; 53941591Ssklower l1--; 54041591Ssklower } 54141591Ssklower from_bcd (e, &u, l1); 54241591Ssklower if (l1 & 0x01) 54341591Ssklower u++; 54441591Ssklower 54541591Ssklower parse_facilities (u, sa); 54641591Ssklower u += *u + 1; 54741591Ssklower sa -> x25_udlen = min (16, ((octet *)xp) + len - u); 54841591Ssklower if (sa -> x25_udlen < 0) 54941591Ssklower sa -> x25_udlen = 0; 55041591Ssklower bcopy ((caddr_t)u, sa -> x25_udata, (unsigned)sa -> x25_udlen); 55141591Ssklower 55241591Ssklower /* 55341591Ssklower * Now, loop through the listen sockets looking for a match on the 55441591Ssklower * PID. That is the first four octets of the user data field. This 55541591Ssklower * is the closest thing to a port number for X.25 packets. What it 55641591Ssklower * does provide is away of multiplexing services at the user level. 55741591Ssklower */ 55841591Ssklower 55941591Ssklower for (l = pk_listenhead; l; l = l -> lcd_listen) { 56041591Ssklower struct sockaddr_x25 *sxp = l -> lcd_ceaddr; 56141591Ssklower 56241591Ssklower if (bcmp (sxp -> x25_udata, sa -> x25_udata, sxp->x25_udlen)) 56341591Ssklower continue; 56445165Ssklower if (sxp -> x25_net && 56545165Ssklower sxp -> x25_net != pkp->pk_xc.xc_addr.x25_net) 56641591Ssklower continue; 56741591Ssklower /* 56841591Ssklower * don't accept incoming collect calls unless 56941591Ssklower * the server sets the reverse charging option. 57041591Ssklower */ 57141591Ssklower if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 && 57241591Ssklower sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) { 57341591Ssklower errstr = "incoming collect call refused"; 57441591Ssklower break; 57541591Ssklower } 57642277Ssklower if (l -> lcd_so) { 57745165Ssklower if (so = sonewconn (l -> lcd_so, SS_ISCONNECTED)) 57842277Ssklower lcp = (struct pklcd *) so -> so_pcb; 57942277Ssklower } else 58042277Ssklower lcp = pk_attach((struct socket *) 0); 58142277Ssklower if (lcp == 0) { 58241591Ssklower /* 58341591Ssklower * Insufficient space or too many unaccepted 58441591Ssklower * connections. Just throw the call away. 58541591Ssklower */ 58641591Ssklower errstr = "server malfunction"; 58741591Ssklower break; 58841591Ssklower } 58943361Ssklower lcp -> lcd_upper = l -> lcd_upper; 59043361Ssklower lcp -> lcd_upnext = l -> lcd_upnext; 59141591Ssklower lcp -> lcd_lcn = lcn; 59241591Ssklower lcp -> lcd_state = RECEIVED_CALL; 59341591Ssklower lcp -> lcd_craddr = sa; 59441591Ssklower sa -> x25_opts.op_flags |= sxp -> x25_opts.op_flags & 59541591Ssklower ~X25_REVERSE_CHARGE; 59641591Ssklower pk_assoc (pkp, lcp, sa); 59741591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED); 59843361Ssklower if (so) { 59943361Ssklower pk_output (lcp); 60042277Ssklower soisconnected (so); 60143361Ssklower } else if (lcp->lcd_upper) 602*45297Ssklower (*lcp->lcd_upper)(lcp, m); 60341591Ssklower return; 60441591Ssklower } 60541591Ssklower 60641591Ssklower /* 60741591Ssklower * If the call fails for whatever reason, we still need to build a 60841591Ssklower * skeleton LCD in order to be able to properly receive the CLEAR 60941591Ssklower * CONFIRMATION. 61041591Ssklower */ 61141591Ssklower #ifdef WATERLOO /* be explicit */ 61241591Ssklower if (l == 0 && bcmp(sa->x25_udata, "ean", 3) == 0) 61341591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s", 61441591Ssklower sa->x25_addr, sa->x25_udata[3] & 0xff, errstr); 61541591Ssklower else if (l == 0 && bcmp(sa->x25_udata, "\1\0\0\0", 4) == 0) 61641591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s", 61741591Ssklower sa->x25_addr, errstr); 61841591Ssklower else 61941591Ssklower #endif 62041591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s", 62141591Ssklower sa -> x25_addr, sa -> x25_udata[0] & 0xff, 62241591Ssklower sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff, 62341591Ssklower sa -> x25_udata[3] & 0xff, errstr); 624*45297Ssklower if ((lcp = pk_attach((struct socket *)0)) == 0) { 625*45297Ssklower (void) m_free (m); 62641591Ssklower return; 62741591Ssklower } 62841591Ssklower lcp -> lcd_lcn = lcn; 62941591Ssklower lcp -> lcd_state = RECEIVED_CALL; 63041591Ssklower pk_assoc (pkp, lcp, sa); 631*45297Ssklower (void) m_free (m); 63241591Ssklower pk_clear (lcp); 63341591Ssklower } 63441591Ssklower 63541591Ssklower static 63641591Ssklower call_accepted (lcp, xp, len) 63741591Ssklower struct pklcd *lcp; 63841591Ssklower struct x25_packet *xp; 63941591Ssklower { 64041591Ssklower register struct x25_calladdr *ap; 64141591Ssklower register octet *fcp; 64241591Ssklower 64341591Ssklower lcp -> lcd_state = DATA_TRANSFER; 644*45297Ssklower if (lcp -> lcd_so) 645*45297Ssklower soisconnected (lcp -> lcd_so); 64641591Ssklower if (len > 3) { 64741591Ssklower ap = (struct x25_calladdr *) &xp -> packet_data; 64841591Ssklower fcp = (octet *) ap -> address_field + (ap -> calling_addrlen + 64941591Ssklower ap -> called_addrlen + 1) / 2; 65041591Ssklower if (fcp + *fcp <= ((octet *)xp) + len) 65141591Ssklower parse_facilities (fcp, lcp -> lcd_ceaddr); 65241591Ssklower } 65341591Ssklower pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr); 65441591Ssklower } 65541591Ssklower 65641591Ssklower static 65741591Ssklower parse_facilities (fcp, sa) 65841591Ssklower register octet *fcp; 65941591Ssklower register struct sockaddr_x25 *sa; 66041591Ssklower { 66141591Ssklower register octet *maxfcp; 66241591Ssklower 66341591Ssklower maxfcp = fcp + *fcp; 66441591Ssklower fcp++; 66541591Ssklower while (fcp < maxfcp) { 66641591Ssklower /* 66741591Ssklower * Ignore national DCE or DTE facilities 66841591Ssklower */ 66941591Ssklower if (*fcp == 0 || *fcp == 0xff) 67041591Ssklower break; 67141591Ssklower switch (*fcp) { 67241591Ssklower case FACILITIES_WINDOWSIZE: 67341591Ssklower sa -> x25_opts.op_wsize = fcp[1]; 67441591Ssklower fcp += 3; 67541591Ssklower break; 67641591Ssklower 67741591Ssklower case FACILITIES_PACKETSIZE: 67841591Ssklower sa -> x25_opts.op_psize = fcp[1]; 67941591Ssklower fcp += 3; 68041591Ssklower break; 68141591Ssklower 68241591Ssklower case FACILITIES_THROUGHPUT: 68341591Ssklower sa -> x25_opts.op_speed = fcp[1]; 68441591Ssklower fcp += 2; 68541591Ssklower break; 68641591Ssklower 68741591Ssklower case FACILITIES_REVERSE_CHARGE: 68841591Ssklower if (fcp[1] & 01) 68941591Ssklower sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE; 69041591Ssklower /* 69141591Ssklower * Datapac specific: for a X.25(1976) DTE, bit 2 69241591Ssklower * indicates a "hi priority" (eg. international) call. 69341591Ssklower */ 69441591Ssklower if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0) 69541591Ssklower sa -> x25_opts.op_psize = X25_PS128; 69641591Ssklower fcp += 2; 69741591Ssklower break; 69841591Ssklower 69941591Ssklower default: 70041591Ssklower /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/ 70141591Ssklower switch ((*fcp & 0xc0) >> 6) { 70241591Ssklower case 0: /* class A */ 70341591Ssklower fcp += 2; 70441591Ssklower break; 70541591Ssklower 70641591Ssklower case 1: 70741591Ssklower fcp += 3; 70841591Ssklower break; 70941591Ssklower 71041591Ssklower case 2: 71141591Ssklower fcp += 4; 71241591Ssklower break; 71341591Ssklower 71441591Ssklower case 3: 71541591Ssklower fcp++; 71641591Ssklower fcp += *fcp; 71741591Ssklower } 71841591Ssklower } 71941591Ssklower } 72041591Ssklower } 72141591Ssklower 72241591Ssklower from_bcd (a, x, len) 72341591Ssklower register char *a; 72441591Ssklower register octet **x; 72541591Ssklower register int len; 72641591Ssklower { 72741591Ssklower register int posn = 0; 72841591Ssklower 72941591Ssklower while (--len >= 0) { 73041591Ssklower if (posn++ & 0x01) 73141591Ssklower *a = *(*x)++ & 0x0f; 73241591Ssklower else 73341591Ssklower *a = (**x >> 4) & 0x0F; 73441591Ssklower *a++ |= 0x30; 73541591Ssklower } 73641591Ssklower } 737