xref: /csrg-svn/sys/netccitt/pk_input.c (revision 41591)
1*41591Ssklower /* Copyright (c) University of British Columbia, 1984 */
2*41591Ssklower 
3*41591Ssklower #include "../h/param.h"
4*41591Ssklower #include "../h/systm.h"
5*41591Ssklower #include "../h/mbuf.h"
6*41591Ssklower #include "../h/socket.h"
7*41591Ssklower #include "../h/protosw.h"
8*41591Ssklower #include "../h/socketvar.h"
9*41591Ssklower #include "../h/errno.h"
10*41591Ssklower 
11*41591Ssklower #include "../net/if.h"
12*41591Ssklower 
13*41591Ssklower #include "../netccitt/x25.h"
14*41591Ssklower #include "../netccitt/pk.h"
15*41591Ssklower #include "../netccitt/pk_var.h"
16*41591Ssklower 
17*41591Ssklower struct pkcb *
18*41591Ssklower pk_newlink (xcp)
19*41591Ssklower struct x25config *xcp;
20*41591Ssklower {
21*41591Ssklower 	register struct pkcb *pkp;
22*41591Ssklower 	register struct mbuf *m;
23*41591Ssklower 	register struct pklcd *lcp;
24*41591Ssklower 	register struct protosw *pp;
25*41591Ssklower 	register unsigned size;
26*41591Ssklower 
27*41591Ssklower 	if (xcp -> xc_ntnlen <= 0 || xcp -> xc_ntnlen > sizeof (xcp -> xc_ntn) * 2)
28*41591Ssklower 		return ((struct pkcb *)0);
29*41591Ssklower #ifdef BSD4_3
30*41591Ssklower 	pp = pffindproto (AF_CCITT, (int)xcp -> xc_lproto, 0);
31*41591Ssklower #else
32*41591Ssklower 	pp = pffindproto (AF_CCITT, (int)xcp -> xc_lproto);
33*41591Ssklower #endif
34*41591Ssklower 	if (pp == 0 || pp -> pr_output == 0) {
35*41591Ssklower 		pk_message (0, xcp, "link level protosw error");
36*41591Ssklower 		return ((struct pkcb *)0);
37*41591Ssklower 	}
38*41591Ssklower 
39*41591Ssklower 	/*
40*41591Ssklower 	 * Allocate a network control block structure
41*41591Ssklower 	 */
42*41591Ssklower 
43*41591Ssklower 	size = sizeof (struct pkcb) + xcp->xc_maxlcn * sizeof (struct pklcd *);
44*41591Ssklower #ifdef sun
45*41591Ssklower 	if (xcp -> xc_maxlcn < 1 || size > mclbytes) {
46*41591Ssklower #else
47*41591Ssklower 	if (xcp -> xc_maxlcn < 1 || size > CLBYTES) {
48*41591Ssklower #endif
49*41591Ssklower 		pk_message (0, xcp, "invalid maxlcn");
50*41591Ssklower 		return ((struct pkcb *)0);
51*41591Ssklower 	}
52*41591Ssklower 	m = m_get (M_DONTWAIT, MT_PCB);
53*41591Ssklower 	if (m == 0)
54*41591Ssklower 		return ((struct pkcb *)0);
55*41591Ssklower 	if (size > MLEN) {
56*41591Ssklower #ifdef sun
57*41591Ssklower 		if (mclget (m) == 0) {
58*41591Ssklower 			m_freem (m);
59*41591Ssklower 			return ((struct pkcb *)0);
60*41591Ssklower 		}
61*41591Ssklower #else
62*41591Ssklower #ifdef BSD4_3
63*41591Ssklower 		MCLGET (m);
64*41591Ssklower 		if (m -> m_len != CLBYTES) {
65*41591Ssklower 			(void) m_free (m);
66*41591Ssklower 			return ((struct pkcb *)0);
67*41591Ssklower 		}
68*41591Ssklower #else
69*41591Ssklower 		register struct mbuf *p;
70*41591Ssklower 
71*41591Ssklower 		MCLGET (p, 1);
72*41591Ssklower 		if (p == 0) {
73*41591Ssklower 			m_freem (m);
74*41591Ssklower 			return ((struct pkcb *)0);
75*41591Ssklower 		}
76*41591Ssklower 		m -> m_off = (int)p - (int)m;
77*41591Ssklower #endif
78*41591Ssklower #endif
79*41591Ssklower 	}
80*41591Ssklower 	pkp = mtod (m, struct pkcb *);
81*41591Ssklower 	bzero ((caddr_t)pkp, size);
82*41591Ssklower 
83*41591Ssklower 	/*
84*41591Ssklower 	 * Allocate a logical channel descriptor for lcn 0
85*41591Ssklower 	 */
86*41591Ssklower 
87*41591Ssklower 	m = m_getclr (M_DONTWAIT, MT_PCB);
88*41591Ssklower 	if (m == 0) {
89*41591Ssklower 		m_freem (dtom (pkp));
90*41591Ssklower 		return ((struct pkcb *)0);
91*41591Ssklower 	}
92*41591Ssklower 	lcp = mtod (m, struct pklcd *);
93*41591Ssklower 	lcp -> lcd_state = READY;
94*41591Ssklower 	lcp -> lcd_pkp = pkp;
95*41591Ssklower 	pkp -> pk_chan[0] = lcp;
96*41591Ssklower 
97*41591Ssklower 	pkp -> pk_output = pp -> pr_output;
98*41591Ssklower 	pkp -> pk_xcp = xcp;
99*41591Ssklower 	pkp -> pk_state = DTE_WAITING;
100*41591Ssklower 	pkp -> pk_maxlcn = xcp -> xc_maxlcn;
101*41591Ssklower 	pkp -> pk_next = pkcbhead;
102*41591Ssklower 	pkcbhead = pkp;
103*41591Ssklower 
104*41591Ssklower 	/*
105*41591Ssklower 	 * set defaults
106*41591Ssklower 	 */
107*41591Ssklower 
108*41591Ssklower 	if (xcp -> xc_pwsize == 0)
109*41591Ssklower 		xcp -> xc_pwsize = DEFAULT_WINDOW_SIZE;
110*41591Ssklower 	if (xcp -> xc_psize == 0)
111*41591Ssklower 		xcp -> xc_psize = X25_PS128;
112*41591Ssklower 	return (pkp);
113*41591Ssklower }
114*41591Ssklower 
115*41591Ssklower /*
116*41591Ssklower  *  This procedure is called by the link level whenever the link
117*41591Ssklower  *  becomes operational, is reset, or when the link goes down.
118*41591Ssklower  */
119*41591Ssklower 
120*41591Ssklower pk_ctlinput (code, xcp)
121*41591Ssklower struct x25config *xcp;
122*41591Ssklower {
123*41591Ssklower 	register struct pkcb *pkp;
124*41591Ssklower 
125*41591Ssklower 	for (pkp = pkcbhead; pkp; pkp = pkp -> pk_next)
126*41591Ssklower 		if (pkp -> pk_xcp == xcp)
127*41591Ssklower 			break;
128*41591Ssklower 
129*41591Ssklower 	if (pkp == 0 && (pkp = pk_newlink (xcp)) == 0)
130*41591Ssklower 		return (EINVAL);
131*41591Ssklower 
132*41591Ssklower 	switch (code) {
133*41591Ssklower 	case PRC_LINKUP:
134*41591Ssklower 		if (pkp -> pk_state == DTE_WAITING)
135*41591Ssklower 			pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
136*41591Ssklower 		break;
137*41591Ssklower 
138*41591Ssklower 	case PRC_LINKDOWN:
139*41591Ssklower 		pk_restart (pkp, -1);	/* Clear all active circuits */
140*41591Ssklower 		pkp -> pk_state = DTE_WAITING;
141*41591Ssklower 		break;
142*41591Ssklower 
143*41591Ssklower 	case PRC_LINKRESET:
144*41591Ssklower 		pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
145*41591Ssklower 		break;
146*41591Ssklower 
147*41591Ssklower 	}
148*41591Ssklower 	return (0);
149*41591Ssklower }
150*41591Ssklower 
151*41591Ssklower /*
152*41591Ssklower  *  X.25 PACKET INPUT
153*41591Ssklower  *
154*41591Ssklower  *  This procedure is called by a link level procedure whenever
155*41591Ssklower  *  an information frame is received. It decodes the packet and
156*41591Ssklower  *  demultiplexes based on the logical channel number.
157*41591Ssklower  *
158*41591Ssklower  */
159*41591Ssklower 
160*41591Ssklower pk_input (m, xcp)
161*41591Ssklower register struct mbuf *m;
162*41591Ssklower struct x25config *xcp;
163*41591Ssklower {
164*41591Ssklower 	register struct x25_packet *xp;
165*41591Ssklower 	register struct pklcd *lcp;
166*41591Ssklower 	register struct socket *so = 0;
167*41591Ssklower 	register struct pkcb *pkp;
168*41591Ssklower 	int  ptype, lcn, lcdstate = LISTEN;
169*41591Ssklower 	static struct x25config *lastxcp;
170*41591Ssklower 	static struct pkcb *lastpkp;
171*41591Ssklower 
172*41591Ssklower 	if (xcp == lastxcp)
173*41591Ssklower 		pkp = lastpkp;
174*41591Ssklower 	else {
175*41591Ssklower 		for (pkp = pkcbhead; ; pkp = pkp -> pk_next) {
176*41591Ssklower 			if (pkp == 0) {
177*41591Ssklower 				pk_message (0, xcp, "pk_input: unknown network");
178*41591Ssklower 				m_freem (m);
179*41591Ssklower 				return;
180*41591Ssklower 			}
181*41591Ssklower 			if (pkp -> pk_xcp == xcp)
182*41591Ssklower 				break;
183*41591Ssklower 		}
184*41591Ssklower 		lastxcp = xcp;
185*41591Ssklower 		lastpkp = pkp;
186*41591Ssklower 	}
187*41591Ssklower 
188*41591Ssklower 	xp = mtod (m, struct x25_packet *);
189*41591Ssklower 	ptype = pk_decode (xp);
190*41591Ssklower 	lcn = xp -> logical_channel_number;
191*41591Ssklower 	lcp = pkp -> pk_chan[lcn];
192*41591Ssklower 
193*41591Ssklower 	/*
194*41591Ssklower 	 *  If the DTE is in Restart  state, then it will ignore data,
195*41591Ssklower 	 *  interrupt, call setup and clearing, flow control and reset
196*41591Ssklower 	 *  packets.
197*41591Ssklower 	 */
198*41591Ssklower 	if (lcn < 0 || lcn > pkp -> pk_maxlcn) {
199*41591Ssklower 		pk_message (lcn, pkp -> pk_xcp, "illegal lcn");
200*41591Ssklower 		m_freem (m);
201*41591Ssklower 		return;
202*41591Ssklower 	}
203*41591Ssklower 
204*41591Ssklower 	pk_trace (pkp -> pk_xcp, xp, "P-In");
205*41591Ssklower 
206*41591Ssklower 	if (pkp -> pk_state != DTE_READY && ptype != RESTART && ptype != RESTART_CONF) {
207*41591Ssklower 		m_freem (m);
208*41591Ssklower 		return;
209*41591Ssklower 	}
210*41591Ssklower 	if (lcp) {
211*41591Ssklower 		so = lcp -> lcd_so;
212*41591Ssklower 		lcdstate = lcp -> lcd_state;
213*41591Ssklower 	} else {
214*41591Ssklower 		if (ptype == CLEAR) {	/* idle line probe (Datapac specific) */
215*41591Ssklower 			/* send response on lcd 0's output queue */
216*41591Ssklower 			lcp -> lcd_template = pk_template (lcn, X25_CLEAR_CONFIRM);
217*41591Ssklower 			pk_output (lcp);
218*41591Ssklower 			m_freem (m);
219*41591Ssklower 			return;
220*41591Ssklower 		}
221*41591Ssklower 		if (ptype != CALL)
222*41591Ssklower 			ptype = INVALID_PACKET;
223*41591Ssklower 	}
224*41591Ssklower 
225*41591Ssklower 	if (lcn == 0 && ptype != RESTART && ptype != RESTART_CONF) {
226*41591Ssklower 		pk_message (0, pkp -> pk_xcp, "illegal ptype (%s) on lcn 0",
227*41591Ssklower 			pk_name[ptype / MAXSTATES]);
228*41591Ssklower 		m_freem (m);
229*41591Ssklower 		return;
230*41591Ssklower 	}
231*41591Ssklower 
232*41591Ssklower 	switch (ptype + lcdstate) {
233*41591Ssklower 	/*
234*41591Ssklower 	 *  Incoming Call packet received.
235*41591Ssklower 	 */
236*41591Ssklower 	case CALL + LISTEN:
237*41591Ssklower 		incoming_call (pkp, xp, m -> m_len);
238*41591Ssklower 		break;
239*41591Ssklower 
240*41591Ssklower 	/*
241*41591Ssklower 	 *  Call collision: Just throw this "incoming call" away since
242*41591Ssklower 	 *  the DCE will ignore it anyway.
243*41591Ssklower 	 */
244*41591Ssklower 	case CALL + SENT_CALL:
245*41591Ssklower 		pk_message ((int)xp -> logical_channel_number, pkp -> pk_xcp,
246*41591Ssklower 			"incoming call collision");
247*41591Ssklower 		break;
248*41591Ssklower 
249*41591Ssklower 	/*
250*41591Ssklower 	 *  Call confirmation packet received. This usually means our
251*41591Ssklower 	 *  previous connect request is now complete.
252*41591Ssklower 	 */
253*41591Ssklower 	case CALL_ACCEPTED + SENT_CALL:
254*41591Ssklower 		call_accepted (lcp, xp, m -> m_len);
255*41591Ssklower 		break;
256*41591Ssklower 
257*41591Ssklower 	/*
258*41591Ssklower 	 *  This condition can only happen if the previous state was
259*41591Ssklower 	 *  SENT_CALL. Just ignore the packet, eventually a clear
260*41591Ssklower 	 *  confirmation should arrive.
261*41591Ssklower 	 */
262*41591Ssklower 	case CALL_ACCEPTED + SENT_CLEAR:
263*41591Ssklower 		break;
264*41591Ssklower 
265*41591Ssklower 	/*
266*41591Ssklower 	 *  Clear packet received. This requires a complete tear down
267*41591Ssklower 	 *  of the virtual circuit.  Free buffers and control blocks.
268*41591Ssklower 	 *  and send a clear confirmation.
269*41591Ssklower 	 */
270*41591Ssklower 	case CLEAR + READY:
271*41591Ssklower 	case CLEAR + RECEIVED_CALL:
272*41591Ssklower 	case CLEAR + SENT_CALL:
273*41591Ssklower 	case CLEAR + DATA_TRANSFER:
274*41591Ssklower 		lcp -> lcd_state = RECEIVED_CLEAR;
275*41591Ssklower 		lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CLEAR_CONFIRM);
276*41591Ssklower 		pk_output (lcp);
277*41591Ssklower 		pk_clearcause (pkp, xp);
278*41591Ssklower 		pk_close (lcp);
279*41591Ssklower 		break;
280*41591Ssklower 
281*41591Ssklower 	/*
282*41591Ssklower 	 *  Clear collision: Treat this clear packet as a confirmation.
283*41591Ssklower 	 */
284*41591Ssklower 	case CLEAR + SENT_CLEAR:
285*41591Ssklower 		pk_close (lcp);
286*41591Ssklower 		break;
287*41591Ssklower 
288*41591Ssklower 	/*
289*41591Ssklower 	 *  Clear confirmation received. This usually means the virtual
290*41591Ssklower 	 *  circuit is now completely removed.
291*41591Ssklower 	 */
292*41591Ssklower 	case CLEAR_CONF + SENT_CLEAR:
293*41591Ssklower 		pk_close (lcp);
294*41591Ssklower 		break;
295*41591Ssklower 
296*41591Ssklower 	/*
297*41591Ssklower 	 *  A clear confirmation on an unassigned logical channel - just
298*41591Ssklower 	 *  ignore it. Note: All other packets on an unassigned channel
299*41591Ssklower 	 *  results in a clear.
300*41591Ssklower 	 */
301*41591Ssklower 	case CLEAR_CONF + READY:
302*41591Ssklower 		break;
303*41591Ssklower 
304*41591Ssklower 	/*
305*41591Ssklower 	 *  Data packet received. Pass on to next level. Move the Q and M
306*41591Ssklower 	 *  bits into the data portion for the next level.
307*41591Ssklower 	 */
308*41591Ssklower 	case DATA + DATA_TRANSFER:
309*41591Ssklower 		if (lcp -> lcd_reset_condition) {
310*41591Ssklower 			ptype = DELETE_PACKET;
311*41591Ssklower 			break;
312*41591Ssklower 		}
313*41591Ssklower 
314*41591Ssklower 		/*
315*41591Ssklower 		 *  Process the P(S) flow control information in this Data packet.
316*41591Ssklower 		 *  Check that the packets arrive in the correct sequence and that
317*41591Ssklower 		 *  they are within the "lcd_input_window". Input window rotation is
318*41591Ssklower 		 *  initiated by the receive interface.
319*41591Ssklower 		 */
320*41591Ssklower 
321*41591Ssklower 		if (PS(xp) != ((lcp -> lcd_rsn + 1) % MODULUS) ||
322*41591Ssklower 			PS(xp) == ((lcp -> lcd_input_window + lcp->lcd_windowsize) % MODULUS)) {
323*41591Ssklower 			m_freem (m);
324*41591Ssklower 			pk_procerror (RESET, lcp, "p(s) flow control error");
325*41591Ssklower 			break;
326*41591Ssklower 		}
327*41591Ssklower 		lcp -> lcd_rsn = PS(xp);
328*41591Ssklower 
329*41591Ssklower 		if (pk_ack (lcp, PR(xp)) != PACKET_OK) {
330*41591Ssklower 			m_freem (m);
331*41591Ssklower 			break;
332*41591Ssklower 		}
333*41591Ssklower 
334*41591Ssklower 		m -> m_off += PKHEADERLN;
335*41591Ssklower 		m -> m_len -= PKHEADERLN;
336*41591Ssklower 		if (lcp -> lcd_flags & X25_MQBIT) {
337*41591Ssklower 			octet *t;
338*41591Ssklower 
339*41591Ssklower 			m -> m_off -= 1;
340*41591Ssklower 			m -> m_len += 1;
341*41591Ssklower 			t = mtod (m, octet *);
342*41591Ssklower 			*t = 0x00;
343*41591Ssklower 			if (xp -> q_bit)
344*41591Ssklower 				*t |= 0x80;
345*41591Ssklower 			if (MBIT(xp))
346*41591Ssklower 				*t |= 0x40;
347*41591Ssklower 		}
348*41591Ssklower 
349*41591Ssklower 		/*
350*41591Ssklower 		 * Discard Q-BIT packets if the application
351*41591Ssklower 		 * doesn't want to be informed of M and Q bit status
352*41591Ssklower 		 */
353*41591Ssklower 		if (xp -> q_bit && (lcp -> lcd_flags & X25_MQBIT) == 0) {
354*41591Ssklower 			m_freem (m);
355*41591Ssklower 			lcp -> lcd_rxcnt++;
356*41591Ssklower 			/*
357*41591Ssklower 			 * NB.  This is dangerous: sending a RR here can
358*41591Ssklower 			 * cause sequence number errors if a previous data
359*41591Ssklower 			 * packet has not yet been passed up to the application
360*41591Ssklower 			 * (RR's are normally generated via PRU_RCVD).
361*41591Ssklower 			 */
362*41591Ssklower 			lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RR);
363*41591Ssklower 			pk_output (lcp);
364*41591Ssklower 		} else {
365*41591Ssklower #ifdef BSD4_3
366*41591Ssklower 			sbappendrecord (&so -> so_rcv, m);
367*41591Ssklower #else
368*41591Ssklower 			sbappend (&so -> so_rcv, m);
369*41591Ssklower #endif
370*41591Ssklower 			sorwakeup (so);
371*41591Ssklower 		}
372*41591Ssklower 		break;
373*41591Ssklower 
374*41591Ssklower 	/*
375*41591Ssklower 	 *  Interrupt packet received.
376*41591Ssklower 	 */
377*41591Ssklower 	case INTERRUPT + DATA_TRANSFER:
378*41591Ssklower 		if (lcp -> lcd_reset_condition)
379*41591Ssklower 			break;
380*41591Ssklower 		lcp -> lcd_intrdata = xp -> packet_data;
381*41591Ssklower 		sohasoutofband (so);
382*41591Ssklower 		lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM);
383*41591Ssklower 		pk_output (lcp);
384*41591Ssklower 		break;
385*41591Ssklower 
386*41591Ssklower 	/*
387*41591Ssklower 	 *  Interrupt confirmation packet received.
388*41591Ssklower 	 */
389*41591Ssklower 	case INTERRUPT_CONF + DATA_TRANSFER:
390*41591Ssklower 		if (lcp -> lcd_reset_condition)
391*41591Ssklower 			break;
392*41591Ssklower 		if (lcp -> lcd_intrconf_pending == TRUE)
393*41591Ssklower 			lcp -> lcd_intrconf_pending = FALSE;
394*41591Ssklower 		else
395*41591Ssklower 			pk_procerror (RESET, lcp, "unexpected packet");
396*41591Ssklower 		break;
397*41591Ssklower 
398*41591Ssklower 	/*
399*41591Ssklower 	 *  Receiver ready received. Rotate the output window and output
400*41591Ssklower 	 *  any data packets waiting transmission.
401*41591Ssklower 	 */
402*41591Ssklower 	case RR + DATA_TRANSFER:
403*41591Ssklower 		if (lcp -> lcd_reset_condition)
404*41591Ssklower 			break;
405*41591Ssklower 		if (pk_ack (lcp, PR(xp)) != PACKET_OK)
406*41591Ssklower 			break;
407*41591Ssklower 		if (lcp -> lcd_rnr_condition == TRUE)
408*41591Ssklower 			lcp -> lcd_rnr_condition = FALSE;
409*41591Ssklower 		pk_output (lcp);
410*41591Ssklower 		break;
411*41591Ssklower 
412*41591Ssklower 	/*
413*41591Ssklower 	 *  Receiver Not Ready received. Packets up to the P(R) can be
414*41591Ssklower 	 *  be sent. Condition is cleared with a RR.
415*41591Ssklower 	 */
416*41591Ssklower 	case RNR + DATA_TRANSFER:
417*41591Ssklower 		if (lcp -> lcd_reset_condition)
418*41591Ssklower 			break;
419*41591Ssklower 		if (pk_ack (lcp, PR(xp)) != PACKET_OK)
420*41591Ssklower 			break;
421*41591Ssklower 		lcp -> lcd_rnr_condition = TRUE;
422*41591Ssklower 		break;
423*41591Ssklower 
424*41591Ssklower 	/*
425*41591Ssklower 	 *  Reset packet received. Set state to FLOW_OPEN.  The Input and
426*41591Ssklower 	 *  Output window edges ar set to zero. Both the send and receive
427*41591Ssklower 	 *  numbers are reset. A confirmation is returned.
428*41591Ssklower 	 */
429*41591Ssklower 	case RESET + DATA_TRANSFER:
430*41591Ssklower 		if (lcp -> lcd_reset_condition)
431*41591Ssklower 			/* Reset collision. Just ignore packet. */
432*41591Ssklower 			break;
433*41591Ssklower 
434*41591Ssklower 		pk_resetcause (pkp, xp);
435*41591Ssklower 		sbflush (&so -> so_snd);
436*41591Ssklower 		sbflush (&so -> so_rcv);
437*41591Ssklower 
438*41591Ssklower 		wakeup ((caddr_t) & so -> so_timeo);
439*41591Ssklower 		sorwakeup (so);
440*41591Ssklower 		sowwakeup (so);
441*41591Ssklower 
442*41591Ssklower 		lcp -> lcd_window_condition = lcp -> lcd_rnr_condition =
443*41591Ssklower 			lcp -> lcd_intrconf_pending = FALSE;
444*41591Ssklower 		lcp -> lcd_output_window = lcp -> lcd_input_window =
445*41591Ssklower 			lcp -> lcd_last_transmitted_pr = 0;
446*41591Ssklower 		lcp -> lcd_ssn = 0;
447*41591Ssklower 		lcp -> lcd_rsn = MODULUS - 1;
448*41591Ssklower 
449*41591Ssklower 		lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM);
450*41591Ssklower 		pk_output (lcp);
451*41591Ssklower 		break;
452*41591Ssklower 
453*41591Ssklower 	/*
454*41591Ssklower 	 *  Reset confirmation received.
455*41591Ssklower 	 */
456*41591Ssklower 	case RESET_CONF + DATA_TRANSFER:
457*41591Ssklower 		if (lcp -> lcd_reset_condition) {
458*41591Ssklower 			lcp -> lcd_reset_condition = FALSE;
459*41591Ssklower 			pk_output (lcp);
460*41591Ssklower 		}
461*41591Ssklower 		else
462*41591Ssklower 			pk_procerror (RESET, lcp, "unexpected packet");
463*41591Ssklower 		break;
464*41591Ssklower 
465*41591Ssklower 	case DATA + SENT_CLEAR:
466*41591Ssklower 		ptype = DELETE_PACKET;
467*41591Ssklower 	case RR + SENT_CLEAR:
468*41591Ssklower 	case RNR + SENT_CLEAR:
469*41591Ssklower 	case INTERRUPT + SENT_CLEAR:
470*41591Ssklower 	case INTERRUPT_CONF + SENT_CLEAR:
471*41591Ssklower 	case RESET + SENT_CLEAR:
472*41591Ssklower 	case RESET_CONF + SENT_CLEAR:
473*41591Ssklower 		/* Just ignore packet if we have sent a CLEAR already.
474*41591Ssklower 		   */
475*41591Ssklower 		break;
476*41591Ssklower 
477*41591Ssklower 	/*
478*41591Ssklower 	 *  Restart sets all the permanent virtual circuits to the "Data
479*41591Ssklower 	 *  Transfer" stae and  all the switched virtual circuits to the
480*41591Ssklower 	 *  "Ready" state.
481*41591Ssklower 	 */
482*41591Ssklower 	case RESTART + READY:
483*41591Ssklower 		switch (pkp -> pk_state) {
484*41591Ssklower 		case DTE_SENT_RESTART:
485*41591Ssklower 			/* Restart collision. */
486*41591Ssklower 			pkp -> pk_state = DTE_READY;
487*41591Ssklower 			pk_message (0, pkp -> pk_xcp,
488*41591Ssklower 				"Packet level operational");
489*41591Ssklower 			break;
490*41591Ssklower 
491*41591Ssklower 		default:
492*41591Ssklower 			pk_restart (pkp, -1);
493*41591Ssklower 			pk_restartcause (pkp, xp);
494*41591Ssklower 			pkp -> pk_chan[0] -> lcd_template = pk_template (0,
495*41591Ssklower 				X25_RESTART_CONFIRM);
496*41591Ssklower 			pk_output (pkp -> pk_chan[0]);
497*41591Ssklower 		}
498*41591Ssklower 		break;
499*41591Ssklower 
500*41591Ssklower 	/*
501*41591Ssklower 	 *  Restart confirmation received. All logical channels are set
502*41591Ssklower 	 *  to READY.
503*41591Ssklower 	 */
504*41591Ssklower 	case RESTART_CONF + READY:
505*41591Ssklower 		switch (pkp -> pk_state) {
506*41591Ssklower 		case DTE_SENT_RESTART:
507*41591Ssklower 			pkp -> pk_state = DTE_READY;
508*41591Ssklower 			pk_message (0, pkp -> pk_xcp,
509*41591Ssklower 				"Packet level operational");
510*41591Ssklower 			break;
511*41591Ssklower 
512*41591Ssklower 		default:
513*41591Ssklower 			/* Restart local procedure error. */
514*41591Ssklower 			pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR);
515*41591Ssklower 			pkp -> pk_state = DTE_SENT_RESTART;
516*41591Ssklower 		}
517*41591Ssklower 		break;
518*41591Ssklower 
519*41591Ssklower 	default:
520*41591Ssklower 		if (lcp) {
521*41591Ssklower 			pk_procerror (CLEAR, lcp, "unknown packet error");
522*41591Ssklower 			pk_message (lcn, pkp -> pk_xcp,
523*41591Ssklower 				"\"%s\" unexpected in \"%s\" state",
524*41591Ssklower 				pk_name[ptype/MAXSTATES], pk_state[lcdstate]);
525*41591Ssklower 		}
526*41591Ssklower 		else	/* Packets arrived on an unassigned channel.
527*41591Ssklower 			*/
528*41591Ssklower 			pk_message ((int)xp->logical_channel_number, pkp -> pk_xcp,
529*41591Ssklower 				"packet arrived on unassigned lcn");
530*41591Ssklower 		break;
531*41591Ssklower 	}
532*41591Ssklower 	if (ptype != DATA)
533*41591Ssklower 		m_freem (m);
534*41591Ssklower }
535*41591Ssklower 
536*41591Ssklower 
537*41591Ssklower /*
538*41591Ssklower  * This routine handles incoming call packets. It matches the protocol
539*41591Ssklower  * field on the Call User Data field (usually the first four bytes) with
540*41591Ssklower  * sockets awaiting connections.
541*41591Ssklower  */
542*41591Ssklower 
543*41591Ssklower static
544*41591Ssklower incoming_call (pkp, xp, len)
545*41591Ssklower struct pkcb *pkp;
546*41591Ssklower struct x25_packet *xp;
547*41591Ssklower {
548*41591Ssklower 	register struct pklcd *lcp, *l;
549*41591Ssklower 	register struct sockaddr_x25 *sa;
550*41591Ssklower 	register struct x25_calladdr *a;
551*41591Ssklower 	register struct socket *so;
552*41591Ssklower 	struct mbuf *m;
553*41591Ssklower 	register int l1, l2;
554*41591Ssklower 	char *e, *errstr = "server unavailable";
555*41591Ssklower 	octet *u;
556*41591Ssklower 	int lcn = xp -> logical_channel_number;
557*41591Ssklower 
558*41591Ssklower 	/* First, copy the data from the incoming call packet to a X25_socket
559*41591Ssklower 	   descriptor. */
560*41591Ssklower 
561*41591Ssklower 	a = (struct x25_calladdr *) &xp -> packet_data;
562*41591Ssklower 	l1 = a -> calling_addrlen;
563*41591Ssklower 	l2 = a -> called_addrlen;
564*41591Ssklower 	if ((m = m_getclr (M_DONTWAIT, MT_HEADER)) == 0)
565*41591Ssklower 		return;
566*41591Ssklower 	sa = mtod (m, struct sockaddr_x25 *);
567*41591Ssklower 	u = (octet *) (a -> address_field + l2 / 2);
568*41591Ssklower 	e = sa -> x25_addr;
569*41591Ssklower 	if (l2 & 0x01) {
570*41591Ssklower 		*e++ = *u++ & 0x0f;
571*41591Ssklower 		l1--;
572*41591Ssklower 	}
573*41591Ssklower 	from_bcd (e, &u, l1);
574*41591Ssklower 	if (l1 & 0x01)
575*41591Ssklower 		u++;
576*41591Ssklower 
577*41591Ssklower 	parse_facilities (u, sa);
578*41591Ssklower 	u += *u + 1;
579*41591Ssklower 	sa -> x25_udlen = min (16, ((octet *)xp) + len - u);
580*41591Ssklower 	if (sa -> x25_udlen < 0)
581*41591Ssklower 		sa -> x25_udlen = 0;
582*41591Ssklower 	bcopy ((caddr_t)u, sa -> x25_udata, (unsigned)sa -> x25_udlen);
583*41591Ssklower 
584*41591Ssklower 	/*
585*41591Ssklower 	 * Now, loop through the  listen sockets looking for a match on the
586*41591Ssklower 	 * PID. That is  the first  four octets  of the user data field.  This
587*41591Ssklower 	 * is the closest thing to a port number for X.25 packets. What it
588*41591Ssklower 	 * does provide is away of  multiplexing  services at the user level.
589*41591Ssklower 	 */
590*41591Ssklower 
591*41591Ssklower 	for (l = pk_listenhead; l; l = l -> lcd_listen) {
592*41591Ssklower 		struct sockaddr_x25 *sxp = l -> lcd_ceaddr;
593*41591Ssklower 
594*41591Ssklower 		if (bcmp (sxp -> x25_udata, sa -> x25_udata, sxp->x25_udlen))
595*41591Ssklower 			continue;
596*41591Ssklower 		if (sxp -> x25_net && sxp -> x25_net != pkp->pk_xcp->xc_net)
597*41591Ssklower 			continue;
598*41591Ssklower 		/*
599*41591Ssklower 		 * don't accept incoming collect calls unless
600*41591Ssklower 		 * the server sets the reverse charging option.
601*41591Ssklower 		 */
602*41591Ssklower 		if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 &&
603*41591Ssklower 			sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) {
604*41591Ssklower 			errstr = "incoming collect call refused";
605*41591Ssklower 			break;
606*41591Ssklower 		}
607*41591Ssklower 		so = sonewconn (l -> lcd_so);
608*41591Ssklower 		if (so == NULL) {
609*41591Ssklower 			/*
610*41591Ssklower 			 * Insufficient space or too many unaccepted
611*41591Ssklower 			 * connections.  Just throw the call away.
612*41591Ssklower 			 */
613*41591Ssklower 			errstr = "server malfunction";
614*41591Ssklower 			break;
615*41591Ssklower 		}
616*41591Ssklower 		lcp = (struct pklcd *) so -> so_pcb;
617*41591Ssklower 		lcp -> lcd_lcn = lcn;
618*41591Ssklower 		lcp -> lcd_state = RECEIVED_CALL;
619*41591Ssklower 		lcp -> lcd_craddr = sa;
620*41591Ssklower 		sa -> x25_opts.op_flags |= sxp -> x25_opts.op_flags &
621*41591Ssklower 			~X25_REVERSE_CHARGE;
622*41591Ssklower 		pk_assoc (pkp, lcp, sa);
623*41591Ssklower 		lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED);
624*41591Ssklower 		pk_output (lcp);
625*41591Ssklower 		soisconnected (so);
626*41591Ssklower 		return;
627*41591Ssklower 	}
628*41591Ssklower 
629*41591Ssklower 	/*
630*41591Ssklower 	 * If the call fails for whatever reason, we still need to build a
631*41591Ssklower 	 * skeleton LCD in order to be able to properly  receive the CLEAR
632*41591Ssklower 	 * CONFIRMATION.
633*41591Ssklower 	 */
634*41591Ssklower #ifdef WATERLOO		/* be explicit */
635*41591Ssklower 	if (l == 0 && bcmp(sa->x25_udata, "ean", 3) == 0)
636*41591Ssklower 		pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s",
637*41591Ssklower 			sa->x25_addr, sa->x25_udata[3] & 0xff, errstr);
638*41591Ssklower 	else if (l == 0 && bcmp(sa->x25_udata, "\1\0\0\0", 4) == 0)
639*41591Ssklower 		pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s",
640*41591Ssklower 			sa->x25_addr, errstr);
641*41591Ssklower 	else
642*41591Ssklower #endif
643*41591Ssklower 	pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s",
644*41591Ssklower 		sa -> x25_addr, sa -> x25_udata[0] & 0xff,
645*41591Ssklower 		sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff,
646*41591Ssklower 		sa -> x25_udata[3] & 0xff, errstr);
647*41591Ssklower 	if ((m = m_getclr (M_DONTWAIT, MT_HEADER)) == 0) {
648*41591Ssklower 		(void) m_free (dtom (sa));
649*41591Ssklower 		return;
650*41591Ssklower 	}
651*41591Ssklower 	lcp = mtod (m, struct pklcd *);
652*41591Ssklower 	lcp -> lcd_lcn = lcn;
653*41591Ssklower 	lcp -> lcd_state = RECEIVED_CALL;
654*41591Ssklower 	pk_assoc (pkp, lcp, sa);
655*41591Ssklower 	(void) m_free (dtom (sa));
656*41591Ssklower 	pk_clear (lcp);
657*41591Ssklower }
658*41591Ssklower 
659*41591Ssklower static
660*41591Ssklower call_accepted (lcp, xp, len)
661*41591Ssklower struct pklcd *lcp;
662*41591Ssklower struct x25_packet *xp;
663*41591Ssklower {
664*41591Ssklower 	register struct x25_calladdr *ap;
665*41591Ssklower 	register octet *fcp;
666*41591Ssklower 
667*41591Ssklower 	lcp -> lcd_state = DATA_TRANSFER;
668*41591Ssklower 	soisconnected (lcp -> lcd_so);
669*41591Ssklower 	if (len > 3) {
670*41591Ssklower 		ap = (struct x25_calladdr *) &xp -> packet_data;
671*41591Ssklower 		fcp = (octet *) ap -> address_field + (ap -> calling_addrlen +
672*41591Ssklower 			ap -> called_addrlen + 1) / 2;
673*41591Ssklower 		if (fcp + *fcp <= ((octet *)xp) + len)
674*41591Ssklower 			parse_facilities (fcp, lcp -> lcd_ceaddr);
675*41591Ssklower 	}
676*41591Ssklower 	pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr);
677*41591Ssklower }
678*41591Ssklower 
679*41591Ssklower static
680*41591Ssklower parse_facilities (fcp, sa)
681*41591Ssklower register octet *fcp;
682*41591Ssklower register struct sockaddr_x25 *sa;
683*41591Ssklower {
684*41591Ssklower 	register octet *maxfcp;
685*41591Ssklower 
686*41591Ssklower 	maxfcp = fcp + *fcp;
687*41591Ssklower 	fcp++;
688*41591Ssklower 	while (fcp < maxfcp) {
689*41591Ssklower 		/*
690*41591Ssklower 		 * Ignore national DCE or DTE facilities
691*41591Ssklower 		 */
692*41591Ssklower 		if (*fcp == 0 || *fcp == 0xff)
693*41591Ssklower 			break;
694*41591Ssklower 		switch (*fcp) {
695*41591Ssklower 		case FACILITIES_WINDOWSIZE:
696*41591Ssklower 			sa -> x25_opts.op_wsize = fcp[1];
697*41591Ssklower 			fcp += 3;
698*41591Ssklower 			break;
699*41591Ssklower 
700*41591Ssklower 		case FACILITIES_PACKETSIZE:
701*41591Ssklower 			sa -> x25_opts.op_psize = fcp[1];
702*41591Ssklower 			fcp += 3;
703*41591Ssklower 			break;
704*41591Ssklower 
705*41591Ssklower 		case FACILITIES_THROUGHPUT:
706*41591Ssklower 			sa -> x25_opts.op_speed = fcp[1];
707*41591Ssklower 			fcp += 2;
708*41591Ssklower 			break;
709*41591Ssklower 
710*41591Ssklower 		case FACILITIES_REVERSE_CHARGE:
711*41591Ssklower 			if (fcp[1] & 01)
712*41591Ssklower 				sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE;
713*41591Ssklower 			/*
714*41591Ssklower 			 * Datapac specific: for a X.25(1976) DTE, bit 2
715*41591Ssklower 			 * indicates a "hi priority" (eg. international) call.
716*41591Ssklower 			 */
717*41591Ssklower 			if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0)
718*41591Ssklower 				sa -> x25_opts.op_psize = X25_PS128;
719*41591Ssklower 			fcp += 2;
720*41591Ssklower 			break;
721*41591Ssklower 
722*41591Ssklower 		default:
723*41591Ssklower /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/
724*41591Ssklower 			switch ((*fcp & 0xc0) >> 6) {
725*41591Ssklower 			case 0:			/* class A */
726*41591Ssklower 				fcp += 2;
727*41591Ssklower 				break;
728*41591Ssklower 
729*41591Ssklower 			case 1:
730*41591Ssklower 				fcp += 3;
731*41591Ssklower 				break;
732*41591Ssklower 
733*41591Ssklower 			case 2:
734*41591Ssklower 				fcp += 4;
735*41591Ssklower 				break;
736*41591Ssklower 
737*41591Ssklower 			case 3:
738*41591Ssklower 				fcp++;
739*41591Ssklower 				fcp += *fcp;
740*41591Ssklower 			}
741*41591Ssklower 		}
742*41591Ssklower 	}
743*41591Ssklower }
744*41591Ssklower 
745*41591Ssklower from_bcd (a, x, len)
746*41591Ssklower register char *a;
747*41591Ssklower register octet **x;
748*41591Ssklower register int len;
749*41591Ssklower {
750*41591Ssklower 	register int posn = 0;
751*41591Ssklower 
752*41591Ssklower 	while (--len >= 0) {
753*41591Ssklower 		if (posn++ & 0x01)
754*41591Ssklower 			*a = *(*x)++ & 0x0f;
755*41591Ssklower 		else
756*41591Ssklower 			*a = (**x >> 4) & 0x0F;
757*41591Ssklower 		*a++ |= 0x30;
758*41591Ssklower 	}
759*41591Ssklower }
760