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*43361Ssklower * @(#)pk_input.c 7.4 (Berkeley) 06/21/90 1341709Ssklower */ 1441591Ssklower 1541591Ssklower #include "../h/param.h" 1641591Ssklower #include "../h/systm.h" 1741591Ssklower #include "../h/mbuf.h" 1841591Ssklower #include "../h/socket.h" 1941591Ssklower #include "../h/protosw.h" 2041591Ssklower #include "../h/socketvar.h" 2141591Ssklower #include "../h/errno.h" 2241591Ssklower 2341591Ssklower #include "../net/if.h" 2441591Ssklower 2541591Ssklower #include "../netccitt/x25.h" 2641591Ssklower #include "../netccitt/pk.h" 2741591Ssklower #include "../netccitt/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 3442277Ssklower pk_ctlinput (code, pkp) 3542277Ssklower register struct pkcb *pkp; 3641591Ssklower { 3741591Ssklower 3842277Ssklower if (pkp == 0) 3941591Ssklower return (EINVAL); 4041591Ssklower switch (code) { 4141591Ssklower case PRC_LINKUP: 4241591Ssklower if (pkp -> pk_state == DTE_WAITING) 4341591Ssklower pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION); 4441591Ssklower break; 4541591Ssklower 4641591Ssklower case PRC_LINKDOWN: 4741591Ssklower pk_restart (pkp, -1); /* Clear all active circuits */ 4841591Ssklower pkp -> pk_state = DTE_WAITING; 4941591Ssklower break; 5041591Ssklower 5141591Ssklower case PRC_LINKRESET: 5241591Ssklower pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION); 5341591Ssklower break; 5441591Ssklower 5541591Ssklower } 5641591Ssklower return (0); 5741591Ssklower } 5841591Ssklower 5941591Ssklower /* 6041591Ssklower * X.25 PACKET INPUT 6141591Ssklower * 6241591Ssklower * This procedure is called by a link level procedure whenever 6341591Ssklower * an information frame is received. It decodes the packet and 6441591Ssklower * demultiplexes based on the logical channel number. 6541591Ssklower * 6641591Ssklower */ 6741591Ssklower 6841591Ssklower pk_input (m, xcp) 6941591Ssklower register struct mbuf *m; 7041591Ssklower struct x25config *xcp; 7141591Ssklower { 7241591Ssklower register struct x25_packet *xp; 7341591Ssklower register struct pklcd *lcp; 7441591Ssklower register struct socket *so = 0; 7541591Ssklower register struct pkcb *pkp; 7641591Ssklower int ptype, lcn, lcdstate = LISTEN; 7741591Ssklower static struct x25config *lastxcp; 7841591Ssklower static struct pkcb *lastpkp; 7941591Ssklower 8041591Ssklower if (xcp == lastxcp) 8141591Ssklower pkp = lastpkp; 8241591Ssklower else { 8341591Ssklower for (pkp = pkcbhead; ; pkp = pkp -> pk_next) { 8441591Ssklower if (pkp == 0) { 8541591Ssklower pk_message (0, xcp, "pk_input: unknown network"); 8641591Ssklower m_freem (m); 8741591Ssklower return; 8841591Ssklower } 8941591Ssklower if (pkp -> pk_xcp == xcp) 9041591Ssklower break; 9141591Ssklower } 9241591Ssklower lastxcp = xcp; 9341591Ssklower lastpkp = pkp; 9441591Ssklower } 9541591Ssklower 9641591Ssklower xp = mtod (m, struct x25_packet *); 9741591Ssklower ptype = pk_decode (xp); 9841591Ssklower lcn = xp -> logical_channel_number; 9941591Ssklower lcp = pkp -> pk_chan[lcn]; 10041591Ssklower 10141591Ssklower /* 10241591Ssklower * If the DTE is in Restart state, then it will ignore data, 10341591Ssklower * interrupt, call setup and clearing, flow control and reset 10441591Ssklower * packets. 10541591Ssklower */ 10641591Ssklower if (lcn < 0 || lcn > pkp -> pk_maxlcn) { 10741591Ssklower pk_message (lcn, pkp -> pk_xcp, "illegal lcn"); 10841591Ssklower m_freem (m); 10941591Ssklower return; 11041591Ssklower } 11141591Ssklower 11241591Ssklower pk_trace (pkp -> pk_xcp, xp, "P-In"); 11341591Ssklower 11441591Ssklower if (pkp -> pk_state != DTE_READY && ptype != RESTART && ptype != RESTART_CONF) { 11541591Ssklower m_freem (m); 11641591Ssklower return; 11741591Ssklower } 11841591Ssklower if (lcp) { 11941591Ssklower so = lcp -> lcd_so; 12041591Ssklower lcdstate = lcp -> lcd_state; 12141591Ssklower } else { 12241591Ssklower if (ptype == CLEAR) { /* idle line probe (Datapac specific) */ 12341591Ssklower /* send response on lcd 0's output queue */ 12441591Ssklower lcp -> lcd_template = pk_template (lcn, X25_CLEAR_CONFIRM); 12541591Ssklower pk_output (lcp); 12641591Ssklower m_freem (m); 12741591Ssklower return; 12841591Ssklower } 12941591Ssklower if (ptype != CALL) 13041591Ssklower ptype = INVALID_PACKET; 13141591Ssklower } 13241591Ssklower 13341591Ssklower if (lcn == 0 && ptype != RESTART && ptype != RESTART_CONF) { 13441591Ssklower pk_message (0, pkp -> pk_xcp, "illegal ptype (%s) on lcn 0", 13541591Ssklower pk_name[ptype / MAXSTATES]); 13641591Ssklower m_freem (m); 13741591Ssklower return; 13841591Ssklower } 13941591Ssklower 14041591Ssklower switch (ptype + lcdstate) { 14141591Ssklower /* 14241591Ssklower * Incoming Call packet received. 14341591Ssklower */ 14441591Ssklower case CALL + LISTEN: 14541591Ssklower incoming_call (pkp, xp, m -> m_len); 14641591Ssklower break; 14741591Ssklower 14841591Ssklower /* 14941591Ssklower * Call collision: Just throw this "incoming call" away since 15041591Ssklower * the DCE will ignore it anyway. 15141591Ssklower */ 15241591Ssklower case CALL + SENT_CALL: 15341591Ssklower pk_message ((int)xp -> logical_channel_number, pkp -> pk_xcp, 15441591Ssklower "incoming call collision"); 15541591Ssklower break; 15641591Ssklower 15741591Ssklower /* 15841591Ssklower * Call confirmation packet received. This usually means our 15941591Ssklower * previous connect request is now complete. 16041591Ssklower */ 16141591Ssklower case CALL_ACCEPTED + SENT_CALL: 16241591Ssklower call_accepted (lcp, xp, m -> m_len); 16341591Ssklower break; 16441591Ssklower 16541591Ssklower /* 16641591Ssklower * This condition can only happen if the previous state was 16741591Ssklower * SENT_CALL. Just ignore the packet, eventually a clear 16841591Ssklower * confirmation should arrive. 16941591Ssklower */ 17041591Ssklower case CALL_ACCEPTED + SENT_CLEAR: 17141591Ssklower break; 17241591Ssklower 17341591Ssklower /* 17441591Ssklower * Clear packet received. This requires a complete tear down 17541591Ssklower * of the virtual circuit. Free buffers and control blocks. 17641591Ssklower * and send a clear confirmation. 17741591Ssklower */ 17841591Ssklower case CLEAR + READY: 17941591Ssklower case CLEAR + RECEIVED_CALL: 18041591Ssklower case CLEAR + SENT_CALL: 18141591Ssklower case CLEAR + DATA_TRANSFER: 18241591Ssklower lcp -> lcd_state = RECEIVED_CLEAR; 18341591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CLEAR_CONFIRM); 18441591Ssklower pk_output (lcp); 18541591Ssklower pk_clearcause (pkp, xp); 18641591Ssklower pk_close (lcp); 18741591Ssklower break; 18841591Ssklower 18941591Ssklower /* 19041591Ssklower * Clear collision: Treat this clear packet as a confirmation. 19141591Ssklower */ 19241591Ssklower case CLEAR + SENT_CLEAR: 19341591Ssklower pk_close (lcp); 19441591Ssklower break; 19541591Ssklower 19641591Ssklower /* 19741591Ssklower * Clear confirmation received. This usually means the virtual 19841591Ssklower * circuit is now completely removed. 19941591Ssklower */ 20041591Ssklower case CLEAR_CONF + SENT_CLEAR: 20141591Ssklower pk_close (lcp); 20241591Ssklower break; 20341591Ssklower 20441591Ssklower /* 20541591Ssklower * A clear confirmation on an unassigned logical channel - just 20641591Ssklower * ignore it. Note: All other packets on an unassigned channel 20741591Ssklower * results in a clear. 20841591Ssklower */ 20941591Ssklower case CLEAR_CONF + READY: 21041591Ssklower break; 21141591Ssklower 21241591Ssklower /* 21341591Ssklower * Data packet received. Pass on to next level. Move the Q and M 21441591Ssklower * bits into the data portion for the next level. 21541591Ssklower */ 21641591Ssklower case DATA + DATA_TRANSFER: 21741591Ssklower if (lcp -> lcd_reset_condition) { 21841591Ssklower ptype = DELETE_PACKET; 21941591Ssklower break; 22041591Ssklower } 22141591Ssklower 22241591Ssklower /* 22341591Ssklower * Process the P(S) flow control information in this Data packet. 22441591Ssklower * Check that the packets arrive in the correct sequence and that 22541591Ssklower * they are within the "lcd_input_window". Input window rotation is 22641591Ssklower * initiated by the receive interface. 22741591Ssklower */ 22841591Ssklower 22941591Ssklower if (PS(xp) != ((lcp -> lcd_rsn + 1) % MODULUS) || 23041591Ssklower PS(xp) == ((lcp -> lcd_input_window + lcp->lcd_windowsize) % MODULUS)) { 23141591Ssklower m_freem (m); 23241591Ssklower pk_procerror (RESET, lcp, "p(s) flow control error"); 23341591Ssklower break; 23441591Ssklower } 23541591Ssklower lcp -> lcd_rsn = PS(xp); 23641591Ssklower 23741591Ssklower if (pk_ack (lcp, PR(xp)) != PACKET_OK) { 23841591Ssklower m_freem (m); 23941591Ssklower break; 24041591Ssklower } 24141591Ssklower 242*43361Ssklower m -> m_data += PKHEADERLN; 24341591Ssklower m -> m_len -= PKHEADERLN; 24441591Ssklower if (lcp -> lcd_flags & X25_MQBIT) { 24541591Ssklower octet *t; 24641591Ssklower 247*43361Ssklower m -> m_data -= 1; 24841591Ssklower m -> m_len += 1; 24941591Ssklower t = mtod (m, octet *); 25041591Ssklower *t = 0x00; 25141591Ssklower if (xp -> q_bit) 25241591Ssklower *t |= 0x80; 25341591Ssklower if (MBIT(xp)) 25441591Ssklower *t |= 0x40; 25541591Ssklower } 25641591Ssklower 25741591Ssklower /* 25841591Ssklower * Discard Q-BIT packets if the application 25941591Ssklower * doesn't want to be informed of M and Q bit status 26041591Ssklower */ 26141591Ssklower if (xp -> q_bit && (lcp -> lcd_flags & X25_MQBIT) == 0) { 26241591Ssklower m_freem (m); 26341591Ssklower lcp -> lcd_rxcnt++; 26441591Ssklower /* 26541591Ssklower * NB. This is dangerous: sending a RR here can 26641591Ssklower * cause sequence number errors if a previous data 26741591Ssklower * packet has not yet been passed up to the application 26841591Ssklower * (RR's are normally generated via PRU_RCVD). 26941591Ssklower */ 27041591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RR); 27141591Ssklower pk_output (lcp); 27241591Ssklower } else { 27341591Ssklower #ifdef BSD4_3 27441591Ssklower sbappendrecord (&so -> so_rcv, m); 27541591Ssklower #else 27641591Ssklower sbappend (&so -> so_rcv, m); 27741591Ssklower #endif 27841591Ssklower sorwakeup (so); 27941591Ssklower } 28041591Ssklower break; 28141591Ssklower 28241591Ssklower /* 28341591Ssklower * Interrupt packet received. 28441591Ssklower */ 28541591Ssklower case INTERRUPT + DATA_TRANSFER: 28641591Ssklower if (lcp -> lcd_reset_condition) 28741591Ssklower break; 28841591Ssklower lcp -> lcd_intrdata = xp -> packet_data; 28941591Ssklower sohasoutofband (so); 29041591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM); 29141591Ssklower pk_output (lcp); 29241591Ssklower break; 29341591Ssklower 29441591Ssklower /* 29541591Ssklower * Interrupt confirmation packet received. 29641591Ssklower */ 29741591Ssklower case INTERRUPT_CONF + DATA_TRANSFER: 29841591Ssklower if (lcp -> lcd_reset_condition) 29941591Ssklower break; 30041591Ssklower if (lcp -> lcd_intrconf_pending == TRUE) 30141591Ssklower lcp -> lcd_intrconf_pending = FALSE; 30241591Ssklower else 30341591Ssklower pk_procerror (RESET, lcp, "unexpected packet"); 30441591Ssklower break; 30541591Ssklower 30641591Ssklower /* 30741591Ssklower * Receiver ready received. Rotate the output window and output 30841591Ssklower * any data packets waiting transmission. 30941591Ssklower */ 31041591Ssklower case RR + DATA_TRANSFER: 31141591Ssklower if (lcp -> lcd_reset_condition) 31241591Ssklower break; 31341591Ssklower if (pk_ack (lcp, PR(xp)) != PACKET_OK) 31441591Ssklower break; 31541591Ssklower if (lcp -> lcd_rnr_condition == TRUE) 31641591Ssklower lcp -> lcd_rnr_condition = FALSE; 31741591Ssklower pk_output (lcp); 31841591Ssklower break; 31941591Ssklower 32041591Ssklower /* 32141591Ssklower * Receiver Not Ready received. Packets up to the P(R) can be 32241591Ssklower * be sent. Condition is cleared with a RR. 32341591Ssklower */ 32441591Ssklower case RNR + DATA_TRANSFER: 32541591Ssklower if (lcp -> lcd_reset_condition) 32641591Ssklower break; 32741591Ssklower if (pk_ack (lcp, PR(xp)) != PACKET_OK) 32841591Ssklower break; 32941591Ssklower lcp -> lcd_rnr_condition = TRUE; 33041591Ssklower break; 33141591Ssklower 33241591Ssklower /* 33341591Ssklower * Reset packet received. Set state to FLOW_OPEN. The Input and 33441591Ssklower * Output window edges ar set to zero. Both the send and receive 33541591Ssklower * numbers are reset. A confirmation is returned. 33641591Ssklower */ 33741591Ssklower case RESET + DATA_TRANSFER: 33841591Ssklower if (lcp -> lcd_reset_condition) 33941591Ssklower /* Reset collision. Just ignore packet. */ 34041591Ssklower break; 34141591Ssklower 34241591Ssklower pk_resetcause (pkp, xp); 34341591Ssklower sbflush (&so -> so_snd); 34441591Ssklower sbflush (&so -> so_rcv); 34541591Ssklower 34641591Ssklower wakeup ((caddr_t) & so -> so_timeo); 34741591Ssklower sorwakeup (so); 34841591Ssklower sowwakeup (so); 34941591Ssklower 35041591Ssklower lcp -> lcd_window_condition = lcp -> lcd_rnr_condition = 35141591Ssklower lcp -> lcd_intrconf_pending = FALSE; 35241591Ssklower lcp -> lcd_output_window = lcp -> lcd_input_window = 35341591Ssklower lcp -> lcd_last_transmitted_pr = 0; 35441591Ssklower lcp -> lcd_ssn = 0; 35541591Ssklower lcp -> lcd_rsn = MODULUS - 1; 35641591Ssklower 35741591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM); 35841591Ssklower pk_output (lcp); 35941591Ssklower break; 36041591Ssklower 36141591Ssklower /* 36241591Ssklower * Reset confirmation received. 36341591Ssklower */ 36441591Ssklower case RESET_CONF + DATA_TRANSFER: 36541591Ssklower if (lcp -> lcd_reset_condition) { 36641591Ssklower lcp -> lcd_reset_condition = FALSE; 36741591Ssklower pk_output (lcp); 36841591Ssklower } 36941591Ssklower else 37041591Ssklower pk_procerror (RESET, lcp, "unexpected packet"); 37141591Ssklower break; 37241591Ssklower 37341591Ssklower case DATA + SENT_CLEAR: 37441591Ssklower ptype = DELETE_PACKET; 37541591Ssklower case RR + SENT_CLEAR: 37641591Ssklower case RNR + SENT_CLEAR: 37741591Ssklower case INTERRUPT + SENT_CLEAR: 37841591Ssklower case INTERRUPT_CONF + SENT_CLEAR: 37941591Ssklower case RESET + SENT_CLEAR: 38041591Ssklower case RESET_CONF + SENT_CLEAR: 38141591Ssklower /* Just ignore packet if we have sent a CLEAR already. 38241591Ssklower */ 38341591Ssklower break; 38441591Ssklower 38541591Ssklower /* 38641591Ssklower * Restart sets all the permanent virtual circuits to the "Data 38741591Ssklower * Transfer" stae and all the switched virtual circuits to the 38841591Ssklower * "Ready" state. 38941591Ssklower */ 39041591Ssklower case RESTART + READY: 39141591Ssklower switch (pkp -> pk_state) { 39241591Ssklower case DTE_SENT_RESTART: 39341591Ssklower /* Restart collision. */ 39441591Ssklower pkp -> pk_state = DTE_READY; 39541591Ssklower pk_message (0, pkp -> pk_xcp, 39641591Ssklower "Packet level operational"); 39741591Ssklower break; 39841591Ssklower 39941591Ssklower default: 40041591Ssklower pk_restart (pkp, -1); 40141591Ssklower pk_restartcause (pkp, xp); 40241591Ssklower pkp -> pk_chan[0] -> lcd_template = pk_template (0, 40341591Ssklower X25_RESTART_CONFIRM); 40441591Ssklower pk_output (pkp -> pk_chan[0]); 40541591Ssklower } 40641591Ssklower break; 40741591Ssklower 40841591Ssklower /* 40941591Ssklower * Restart confirmation received. All logical channels are set 41041591Ssklower * to READY. 41141591Ssklower */ 41241591Ssklower case RESTART_CONF + READY: 41341591Ssklower switch (pkp -> pk_state) { 41441591Ssklower case DTE_SENT_RESTART: 41541591Ssklower pkp -> pk_state = DTE_READY; 41641591Ssklower pk_message (0, pkp -> pk_xcp, 41741591Ssklower "Packet level operational"); 41841591Ssklower break; 41941591Ssklower 42041591Ssklower default: 42141591Ssklower /* Restart local procedure error. */ 42241591Ssklower pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR); 42341591Ssklower pkp -> pk_state = DTE_SENT_RESTART; 42441591Ssklower } 42541591Ssklower break; 42641591Ssklower 42741591Ssklower default: 42841591Ssklower if (lcp) { 42941591Ssklower pk_procerror (CLEAR, lcp, "unknown packet error"); 43041591Ssklower pk_message (lcn, pkp -> pk_xcp, 43141591Ssklower "\"%s\" unexpected in \"%s\" state", 43241591Ssklower pk_name[ptype/MAXSTATES], pk_state[lcdstate]); 43341591Ssklower } 43441591Ssklower else /* Packets arrived on an unassigned channel. 43541591Ssklower */ 43641591Ssklower pk_message ((int)xp->logical_channel_number, pkp -> pk_xcp, 43741591Ssklower "packet arrived on unassigned lcn"); 43841591Ssklower break; 43941591Ssklower } 44041591Ssklower if (ptype != DATA) 44141591Ssklower m_freem (m); 44241591Ssklower } 44341591Ssklower 44441591Ssklower 44541591Ssklower /* 44641591Ssklower * This routine handles incoming call packets. It matches the protocol 44741591Ssklower * field on the Call User Data field (usually the first four bytes) with 44841591Ssklower * sockets awaiting connections. 44941591Ssklower */ 45041591Ssklower 45141591Ssklower static 45241591Ssklower incoming_call (pkp, xp, len) 45341591Ssklower struct pkcb *pkp; 45441591Ssklower struct x25_packet *xp; 45541591Ssklower { 45642277Ssklower register struct pklcd *lcp = 0, *l; 45741591Ssklower register struct sockaddr_x25 *sa; 45841591Ssklower register struct x25_calladdr *a; 45942277Ssklower register struct socket *so = 0; 46041591Ssklower struct mbuf *m; 46141591Ssklower register int l1, l2; 46241591Ssklower char *e, *errstr = "server unavailable"; 46341591Ssklower octet *u; 46441591Ssklower int lcn = xp -> logical_channel_number; 46541591Ssklower 46641591Ssklower /* First, copy the data from the incoming call packet to a X25_socket 46741591Ssklower descriptor. */ 46841591Ssklower 46941591Ssklower a = (struct x25_calladdr *) &xp -> packet_data; 47041591Ssklower l1 = a -> calling_addrlen; 47141591Ssklower l2 = a -> called_addrlen; 47241591Ssklower if ((m = m_getclr (M_DONTWAIT, MT_HEADER)) == 0) 47341591Ssklower return; 47441591Ssklower sa = mtod (m, struct sockaddr_x25 *); 47541591Ssklower u = (octet *) (a -> address_field + l2 / 2); 47641591Ssklower e = sa -> x25_addr; 47741591Ssklower if (l2 & 0x01) { 47841591Ssklower *e++ = *u++ & 0x0f; 47941591Ssklower l1--; 48041591Ssklower } 48141591Ssklower from_bcd (e, &u, l1); 48241591Ssklower if (l1 & 0x01) 48341591Ssklower u++; 48441591Ssklower 48541591Ssklower parse_facilities (u, sa); 48641591Ssklower u += *u + 1; 48741591Ssklower sa -> x25_udlen = min (16, ((octet *)xp) + len - u); 48841591Ssklower if (sa -> x25_udlen < 0) 48941591Ssklower sa -> x25_udlen = 0; 49041591Ssklower bcopy ((caddr_t)u, sa -> x25_udata, (unsigned)sa -> x25_udlen); 49141591Ssklower 49241591Ssklower /* 49341591Ssklower * Now, loop through the listen sockets looking for a match on the 49441591Ssklower * PID. That is the first four octets of the user data field. This 49541591Ssklower * is the closest thing to a port number for X.25 packets. What it 49641591Ssklower * does provide is away of multiplexing services at the user level. 49741591Ssklower */ 49841591Ssklower 49941591Ssklower for (l = pk_listenhead; l; l = l -> lcd_listen) { 50041591Ssklower struct sockaddr_x25 *sxp = l -> lcd_ceaddr; 50141591Ssklower 50241591Ssklower if (bcmp (sxp -> x25_udata, sa -> x25_udata, sxp->x25_udlen)) 50341591Ssklower continue; 50441591Ssklower if (sxp -> x25_net && sxp -> x25_net != pkp->pk_xcp->xc_net) 50541591Ssklower continue; 50641591Ssklower /* 50741591Ssklower * don't accept incoming collect calls unless 50841591Ssklower * the server sets the reverse charging option. 50941591Ssklower */ 51041591Ssklower if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 && 51141591Ssklower sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) { 51241591Ssklower errstr = "incoming collect call refused"; 51341591Ssklower break; 51441591Ssklower } 51542277Ssklower if (l -> lcd_so) { 51642277Ssklower if (so = sonewconn (l -> lcd_so, SO_ISCONNETED)) 51742277Ssklower lcp = (struct pklcd *) so -> so_pcb; 51842277Ssklower } else 51942277Ssklower lcp = pk_attach((struct socket *) 0); 52042277Ssklower if (lcp == 0) { 52141591Ssklower /* 52241591Ssklower * Insufficient space or too many unaccepted 52341591Ssklower * connections. Just throw the call away. 52441591Ssklower */ 52541591Ssklower errstr = "server malfunction"; 52641591Ssklower break; 52741591Ssklower } 528*43361Ssklower lcp -> lcd_upper = l -> lcd_upper; 529*43361Ssklower lcp -> lcd_upnext = l -> lcd_upnext; 53041591Ssklower lcp -> lcd_lcn = lcn; 53141591Ssklower lcp -> lcd_state = RECEIVED_CALL; 53241591Ssklower lcp -> lcd_craddr = sa; 53341591Ssklower sa -> x25_opts.op_flags |= sxp -> x25_opts.op_flags & 53441591Ssklower ~X25_REVERSE_CHARGE; 53541591Ssklower pk_assoc (pkp, lcp, sa); 53641591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED); 537*43361Ssklower if (so) { 538*43361Ssklower pk_output (lcp); 53942277Ssklower soisconnected (so); 540*43361Ssklower } else if (lcp->lcd_upper) 541*43361Ssklower (*lcp->lcd_upper)(lcp); 54241591Ssklower return; 54341591Ssklower } 54441591Ssklower 54541591Ssklower /* 54641591Ssklower * If the call fails for whatever reason, we still need to build a 54741591Ssklower * skeleton LCD in order to be able to properly receive the CLEAR 54841591Ssklower * CONFIRMATION. 54941591Ssklower */ 55041591Ssklower #ifdef WATERLOO /* be explicit */ 55141591Ssklower if (l == 0 && bcmp(sa->x25_udata, "ean", 3) == 0) 55241591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s", 55341591Ssklower sa->x25_addr, sa->x25_udata[3] & 0xff, errstr); 55441591Ssklower else if (l == 0 && bcmp(sa->x25_udata, "\1\0\0\0", 4) == 0) 55541591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s", 55641591Ssklower sa->x25_addr, errstr); 55741591Ssklower else 55841591Ssklower #endif 55941591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s", 56041591Ssklower sa -> x25_addr, sa -> x25_udata[0] & 0xff, 56141591Ssklower sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff, 56241591Ssklower sa -> x25_udata[3] & 0xff, errstr); 56341591Ssklower if ((m = m_getclr (M_DONTWAIT, MT_HEADER)) == 0) { 56441591Ssklower (void) m_free (dtom (sa)); 56541591Ssklower return; 56641591Ssklower } 56741591Ssklower lcp = mtod (m, struct pklcd *); 56841591Ssklower lcp -> lcd_lcn = lcn; 56941591Ssklower lcp -> lcd_state = RECEIVED_CALL; 57041591Ssklower pk_assoc (pkp, lcp, sa); 57141591Ssklower (void) m_free (dtom (sa)); 57241591Ssklower pk_clear (lcp); 57341591Ssklower } 57441591Ssklower 57541591Ssklower static 57641591Ssklower call_accepted (lcp, xp, len) 57741591Ssklower struct pklcd *lcp; 57841591Ssklower struct x25_packet *xp; 57941591Ssklower { 58041591Ssklower register struct x25_calladdr *ap; 58141591Ssklower register octet *fcp; 58241591Ssklower 58341591Ssklower lcp -> lcd_state = DATA_TRANSFER; 58441591Ssklower soisconnected (lcp -> lcd_so); 58541591Ssklower if (len > 3) { 58641591Ssklower ap = (struct x25_calladdr *) &xp -> packet_data; 58741591Ssklower fcp = (octet *) ap -> address_field + (ap -> calling_addrlen + 58841591Ssklower ap -> called_addrlen + 1) / 2; 58941591Ssklower if (fcp + *fcp <= ((octet *)xp) + len) 59041591Ssklower parse_facilities (fcp, lcp -> lcd_ceaddr); 59141591Ssklower } 59241591Ssklower pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr); 59341591Ssklower } 59441591Ssklower 59541591Ssklower static 59641591Ssklower parse_facilities (fcp, sa) 59741591Ssklower register octet *fcp; 59841591Ssklower register struct sockaddr_x25 *sa; 59941591Ssklower { 60041591Ssklower register octet *maxfcp; 60141591Ssklower 60241591Ssklower maxfcp = fcp + *fcp; 60341591Ssklower fcp++; 60441591Ssklower while (fcp < maxfcp) { 60541591Ssklower /* 60641591Ssklower * Ignore national DCE or DTE facilities 60741591Ssklower */ 60841591Ssklower if (*fcp == 0 || *fcp == 0xff) 60941591Ssklower break; 61041591Ssklower switch (*fcp) { 61141591Ssklower case FACILITIES_WINDOWSIZE: 61241591Ssklower sa -> x25_opts.op_wsize = fcp[1]; 61341591Ssklower fcp += 3; 61441591Ssklower break; 61541591Ssklower 61641591Ssklower case FACILITIES_PACKETSIZE: 61741591Ssklower sa -> x25_opts.op_psize = fcp[1]; 61841591Ssklower fcp += 3; 61941591Ssklower break; 62041591Ssklower 62141591Ssklower case FACILITIES_THROUGHPUT: 62241591Ssklower sa -> x25_opts.op_speed = fcp[1]; 62341591Ssklower fcp += 2; 62441591Ssklower break; 62541591Ssklower 62641591Ssklower case FACILITIES_REVERSE_CHARGE: 62741591Ssklower if (fcp[1] & 01) 62841591Ssklower sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE; 62941591Ssklower /* 63041591Ssklower * Datapac specific: for a X.25(1976) DTE, bit 2 63141591Ssklower * indicates a "hi priority" (eg. international) call. 63241591Ssklower */ 63341591Ssklower if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0) 63441591Ssklower sa -> x25_opts.op_psize = X25_PS128; 63541591Ssklower fcp += 2; 63641591Ssklower break; 63741591Ssklower 63841591Ssklower default: 63941591Ssklower /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/ 64041591Ssklower switch ((*fcp & 0xc0) >> 6) { 64141591Ssklower case 0: /* class A */ 64241591Ssklower fcp += 2; 64341591Ssklower break; 64441591Ssklower 64541591Ssklower case 1: 64641591Ssklower fcp += 3; 64741591Ssklower break; 64841591Ssklower 64941591Ssklower case 2: 65041591Ssklower fcp += 4; 65141591Ssklower break; 65241591Ssklower 65341591Ssklower case 3: 65441591Ssklower fcp++; 65541591Ssklower fcp += *fcp; 65641591Ssklower } 65741591Ssklower } 65841591Ssklower } 65941591Ssklower } 66041591Ssklower 66141591Ssklower from_bcd (a, x, len) 66241591Ssklower register char *a; 66341591Ssklower register octet **x; 66441591Ssklower register int len; 66541591Ssklower { 66641591Ssklower register int posn = 0; 66741591Ssklower 66841591Ssklower while (--len >= 0) { 66941591Ssklower if (posn++ & 0x01) 67041591Ssklower *a = *(*x)++ & 0x0f; 67141591Ssklower else 67241591Ssklower *a = (**x >> 4) & 0x0F; 67341591Ssklower *a++ |= 0x30; 67441591Ssklower } 67541591Ssklower } 676