xref: /csrg-svn/sys/netccitt/pk_input.c (revision 57024)
141709Ssklower /*
241709Ssklower  * Copyright (c) University of British Columbia, 1984
3*57024Ssklower  * Copyright (C) Computer Science Department IV,
4*57024Ssklower  * 		 University of Erlangen-Nuremberg, Germany, 1992
5*57024Ssklower  * Copyright (c) 1991, 1992  The Regents of the University of California.
641709Ssklower  * All rights reserved.
741709Ssklower  *
8*57024Ssklower  * This code is derived from software contributed to Berkeley by the
9*57024Ssklower  * Laboratory for Computation Vision and the Computer Science Department
10*57024Ssklower  * of the the University of British Columbia and the Computer Science
11*57024Ssklower  * Department (IV) of the University of Erlangen-Nuremberg, Germany.
1241709Ssklower  *
1341709Ssklower  * %sccs.include.redist.c%
1441709Ssklower  *
15*57024Ssklower  *	@(#)pk_input.c	7.17 (Berkeley) 12/08/92
1641709Ssklower  */
1741591Ssklower 
1856530Sbostic #include <sys/param.h>
1956530Sbostic #include <sys/systm.h>
2056530Sbostic #include <sys/mbuf.h>
2156530Sbostic #include <sys/socket.h>
2256530Sbostic #include <sys/protosw.h>
2356530Sbostic #include <sys/socketvar.h>
2456530Sbostic #include <sys/errno.h>
2541591Ssklower 
2656530Sbostic #include <net/if.h>
2741591Ssklower 
28*57024Ssklower #include <netccitt/dll.h>
2956530Sbostic #include <netccitt/x25.h>
3056530Sbostic #include <netccitt/pk.h>
3156530Sbostic #include <netccitt/pk_var.h>
32*57024Ssklower #include <netccitt/llc_var.h>
3341591Ssklower 
34*57024Ssklower struct pkcb_q pkcb_q = {&pkcb_q, &pkcb_q};
35*57024Ssklower 
36*57024Ssklower /*
37*57024Ssklower  * ccittintr() is the generic interrupt handler for HDLC, LLC2, and X.25. This
38*57024Ssklower  * allows to have kernel running X.25 but no HDLC or LLC2 or both (in case we
39*57024Ssklower  * employ boards that do all the stuff themselves, e.g. ADAX X.25 or TPS ISDN.)
40*57024Ssklower  */
41*57024Ssklower void
42*57024Ssklower ccittintr()
43*57024Ssklower {
44*57024Ssklower 	extern struct ifqueue pkintrq;
45*57024Ssklower 	extern struct ifqueue hdintrq;
46*57024Ssklower 	extern struct ifqueue llcintrq;
47*57024Ssklower 
48*57024Ssklower #ifdef HDLC
49*57024Ssklower 	if (hdintrq.ifq_len)
50*57024Ssklower 		hdintr ();
51*57024Ssklower #endif
52*57024Ssklower #ifdef LLC
53*57024Ssklower 	if (llcintrq.ifq_len)
54*57024Ssklower 		llcintr ();
55*57024Ssklower #endif
56*57024Ssklower 	if (pkintrq.ifq_len)
57*57024Ssklower 		pkintr ();
58*57024Ssklower }
59*57024Ssklower 
6049930Ssklower struct pkcb *
6149930Ssklower pk_newlink (ia, llnext)
6249930Ssklower struct x25_ifaddr *ia;
6349930Ssklower caddr_t llnext;
6449930Ssklower {
6549930Ssklower 	register struct x25config *xcp = &ia->ia_xc;
6649930Ssklower 	register struct pkcb *pkp;
6749930Ssklower 	register struct pklcd *lcp;
6849930Ssklower 	register struct protosw *pp;
6949930Ssklower 	unsigned size;
7049930Ssklower 
7149930Ssklower 	pp = pffindproto (AF_CCITT, (int)xcp -> xc_lproto, 0);
7249930Ssklower 	if (pp == 0 || pp -> pr_output == 0) {
7349930Ssklower 		pk_message (0, xcp, "link level protosw error");
7449930Ssklower 		return ((struct pkcb *)0);
7549930Ssklower 	}
7649930Ssklower 	/*
7749930Ssklower 	 * Allocate a network control block structure
7849930Ssklower 	 */
7949930Ssklower 	size = sizeof (struct pkcb);
8049930Ssklower 	pkp = (struct pkcb *)malloc(size, M_PCB, M_WAITOK);
8149930Ssklower 	if (pkp == 0)
8249930Ssklower 		return ((struct pkcb *)0);
8349930Ssklower 	bzero ((caddr_t)pkp, size);
8449930Ssklower 	pkp -> pk_lloutput = pp -> pr_output;
85*57024Ssklower 	pkp -> pk_llctlinput = (caddr_t (*)())pp -> pr_ctlinput;
8649930Ssklower 	pkp -> pk_xcp = xcp;
8749930Ssklower 	pkp -> pk_ia = ia;
8849930Ssklower 	pkp -> pk_state = DTE_WAITING;
8949930Ssklower 	pkp -> pk_llnext = llnext;
90*57024Ssklower 	insque(pkp, &pkcb_q);
9149930Ssklower 
9249930Ssklower 	/*
9349930Ssklower 	 * set defaults
9449930Ssklower 	 */
9549930Ssklower 
9649930Ssklower 	if (xcp -> xc_pwsize == 0)
9749930Ssklower 		xcp -> xc_pwsize = DEFAULT_WINDOW_SIZE;
9849930Ssklower 	if (xcp -> xc_psize == 0)
9949930Ssklower 		xcp -> xc_psize = X25_PS128;
10049930Ssklower 	/*
10149930Ssklower 	 * Allocate logical channel descriptor vector
10249930Ssklower 	 */
10349930Ssklower 
10449930Ssklower 	(void)pk_resize(pkp);
10549930Ssklower 	return (pkp);
10649930Ssklower }
10749930Ssklower 
108*57024Ssklower 
109*57024Ssklower pk_dellink (pkp)
110*57024Ssklower register struct pkcb *pkp;
111*57024Ssklower {
112*57024Ssklower 	register int i;
113*57024Ssklower 	register struct protosw *pp;
114*57024Ssklower 
115*57024Ssklower 	/*
116*57024Ssklower 	 * Essentially we have the choice to
117*57024Ssklower 	 * (a) go ahead and let the route be deleted and
118*57024Ssklower 	 *     leave the pkcb associated with that route
119*57024Ssklower 	 *     as it is, i.e. the connections stay open
120*57024Ssklower 	 * (b) do a pk_disconnect() on all channels associated
121*57024Ssklower 	 *     with the route via the pkcb and then proceed.
122*57024Ssklower 	 *
123*57024Ssklower 	 * For the time being we stick with (b)
124*57024Ssklower 	 */
125*57024Ssklower 
126*57024Ssklower 	for(i = 1; i < pkp->pk_maxlcn; ++i)
127*57024Ssklower 		if (pkp->pk_chan[i])
128*57024Ssklower 			pk_disconnect(pkp->pk_chan[i]);
129*57024Ssklower 
130*57024Ssklower 	/*
131*57024Ssklower 	 * Free the pkcb
132*57024Ssklower 	 */
133*57024Ssklower 
134*57024Ssklower 	/*
135*57024Ssklower 	 * First find the protoswitch to get hold of the link level
136*57024Ssklower 	 * protocol to be notified that the packet level entity is
137*57024Ssklower 	 * dissolving ...
138*57024Ssklower 	 */
139*57024Ssklower 	pp = pffindproto (AF_CCITT, (int)pkp ->pk_xcp -> xc_lproto, 0);
140*57024Ssklower 	if (pp == 0 || pp -> pr_output == 0) {
141*57024Ssklower 		pk_message (0, pkp -> pk_xcp, "link level protosw error");
142*57024Ssklower 		return(EPROTONOSUPPORT);
143*57024Ssklower 	}
144*57024Ssklower 
145*57024Ssklower 	pkp -> pk_refcount--;
146*57024Ssklower 	if (!pkp -> pk_refcount) {
147*57024Ssklower 		struct dll_ctlinfo ctlinfo;
148*57024Ssklower 
149*57024Ssklower 		remque(pkp);
150*57024Ssklower 		if (pkp -> pk_rt -> rt_llinfo == (caddr_t) pkp)
151*57024Ssklower 			pkp -> pk_rt -> rt_llinfo = (caddr_t) NULL;
152*57024Ssklower 
153*57024Ssklower 		/*
154*57024Ssklower 		 * Tell the link level that the pkcb is dissolving
155*57024Ssklower 		 */
156*57024Ssklower 		if (pp -> pr_ctlinput && pkp -> pk_llnext) {
157*57024Ssklower 			ctlinfo.dlcti_pcb = pkp -> pk_llnext;
158*57024Ssklower 			ctlinfo.dlcti_rt = pkp -> pk_rt;
159*57024Ssklower 			(pp -> pr_ctlinput)(PRC_DISCONNECT_REQUEST,
160*57024Ssklower 					    pkp -> pk_xcp, &ctlinfo);
161*57024Ssklower 		}
162*57024Ssklower 		free((caddr_t) pkp -> pk_chan, M_IFADDR);
163*57024Ssklower 		free((caddr_t) pkp, M_PCB);
164*57024Ssklower 	}
165*57024Ssklower 
166*57024Ssklower 	return (0);
167*57024Ssklower }
168*57024Ssklower 
169*57024Ssklower 
17049930Ssklower pk_resize (pkp)
17149930Ssklower register struct pkcb *pkp;
17249930Ssklower {
17349930Ssklower 	struct pklcd *dev_lcp = 0;
17449930Ssklower 	struct x25config *xcp = pkp -> pk_xcp;
17549930Ssklower 	if (pkp -> pk_chan &&
17649930Ssklower 	    (pkp -> pk_maxlcn != xcp -> xc_maxlcn)) {
17749930Ssklower 		pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
17849930Ssklower 		dev_lcp = pkp -> pk_chan[0];
17949930Ssklower 		free ((caddr_t)pkp -> pk_chan, M_IFADDR);
18049930Ssklower 		pkp -> pk_chan = 0;
18149930Ssklower 	}
18249930Ssklower 	if (pkp -> pk_chan == 0) {
18349930Ssklower 		unsigned size;
18449930Ssklower 		pkp -> pk_maxlcn = xcp -> xc_maxlcn;
18549930Ssklower 		size = (pkp -> pk_maxlcn + 1) * sizeof (struct pklcd *);
18649930Ssklower 		pkp -> pk_chan =
18749930Ssklower 			(struct pklcd **) malloc (size, M_IFADDR, M_WAITOK);
18849930Ssklower 		if (pkp -> pk_chan) {
18949930Ssklower 			bzero ((caddr_t)pkp -> pk_chan, size);
19049930Ssklower 			/*
19149930Ssklower 			 * Allocate a logical channel descriptor for lcn 0
19249930Ssklower 			 */
19349930Ssklower 			if (dev_lcp == 0 &&
19449930Ssklower 			    (dev_lcp = pk_attach ((struct socket *)0)) == 0)
19549930Ssklower 				return (ENOBUFS);
19649930Ssklower 			dev_lcp -> lcd_state = READY;
19749930Ssklower 			dev_lcp -> lcd_pkp = pkp;
19849930Ssklower 			pkp -> pk_chan[0] = dev_lcp;
19949930Ssklower 		} else {
20049930Ssklower 			if (dev_lcp)
20149930Ssklower 				pk_close (dev_lcp);
20249930Ssklower 			return (ENOBUFS);
20349930Ssklower 		}
20449930Ssklower 	}
20549930Ssklower 	return 0;
20649930Ssklower }
20749930Ssklower 
20841591Ssklower /*
20941591Ssklower  *  This procedure is called by the link level whenever the link
21041591Ssklower  *  becomes operational, is reset, or when the link goes down.
21141591Ssklower  */
212*57024Ssklower /*VARARGS*/
213*57024Ssklower caddr_t
214*57024Ssklower pk_ctlinput (code, src, addr)
215*57024Ssklower 	struct sockaddr *src;
216*57024Ssklower 	caddr_t addr;
21741591Ssklower {
218*57024Ssklower 	register struct pkcb *pkp = (struct pkcb *)addr;
21941591Ssklower 
22041591Ssklower 	switch (code) {
22141591Ssklower 	case PRC_LINKUP:
22241591Ssklower 		if (pkp -> pk_state == DTE_WAITING)
22341591Ssklower 			pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
22441591Ssklower 		break;
22541591Ssklower 
22641591Ssklower 	case PRC_LINKDOWN:
22741591Ssklower 		pk_restart (pkp, -1);	/* Clear all active circuits */
22841591Ssklower 		pkp -> pk_state = DTE_WAITING;
22941591Ssklower 		break;
23041591Ssklower 
23141591Ssklower 	case PRC_LINKRESET:
23241591Ssklower 		pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
23341591Ssklower 		break;
234*57024Ssklower 
235*57024Ssklower 	case PRC_CONNECT_INDICATION: {
236*57024Ssklower 		struct rtentry *llrt;
23741591Ssklower 
238*57024Ssklower 		if ((llrt = rtalloc1(src, 0)) == 0)
239*57024Ssklower 			return 0;
240*57024Ssklower 		else llrt->rt_refcnt--;
241*57024Ssklower 
242*57024Ssklower 		pkp = (((struct npaidbentry *)llrt->rt_llinfo)->np_rt) ?
243*57024Ssklower 			(struct pkcb *)(((struct npaidbentry *)llrt->rt_llinfo)->np_rt->rt_llinfo) : (struct pkcb *) 0;
244*57024Ssklower 		if (pkp == (struct pkcb *) 0)
245*57024Ssklower 			return 0;
246*57024Ssklower 		pkp->pk_llnext = addr;
247*57024Ssklower 
248*57024Ssklower 		return ((caddr_t) pkp);
24941591Ssklower 	}
250*57024Ssklower 	case PRC_DISCONNECT_INDICATION:
251*57024Ssklower 		pk_restart (pkp, -1) ;  /* Clear all active circuits */
252*57024Ssklower 		pkp->pk_state = DTE_WAITING;
253*57024Ssklower 		pkp->pk_llnext = (caddr_t) 0;
254*57024Ssklower 	}
25541591Ssklower 	return (0);
25641591Ssklower }
25745297Ssklower struct ifqueue pkintrq;
25845297Ssklower /*
25945297Ssklower  * This routine is called if there are semi-smart devices that do HDLC
26045297Ssklower  * in hardware and want to queue the packet and call level 3 directly
26145297Ssklower  */
26245297Ssklower pkintr ()
26345297Ssklower {
26445297Ssklower 	register struct mbuf *m;
26545297Ssklower 	register struct ifaddr *ifa;
26645297Ssklower 	register struct ifnet *ifp;
26745297Ssklower 	register int s;
26841591Ssklower 
26945297Ssklower 	for (;;) {
27045297Ssklower 		s = splimp ();
27145297Ssklower 		IF_DEQUEUE (&pkintrq, m);
27245297Ssklower 		splx (s);
27345297Ssklower 		if (m == 0)
27445297Ssklower 			break;
27545297Ssklower 		if (m->m_len < PKHEADERLN) {
27645297Ssklower 			printf ("pkintr: packet too short (len=%d)\n",
27745297Ssklower 				m->m_len);
27845297Ssklower 			m_freem (m);
27945297Ssklower 			continue;
28045297Ssklower 		}
28149930Ssklower 		pk_input(m);
28245297Ssklower 	}
28345297Ssklower }
28445297Ssklower struct mbuf *pk_bad_packet;
28549593Ssklower struct mbuf_cache pk_input_cache = {0 };
28641591Ssklower /*
28741591Ssklower  *  X.25 PACKET INPUT
28841591Ssklower  *
28941591Ssklower  *  This procedure is called by a link level procedure whenever
29041591Ssklower  *  an information frame is received. It decodes the packet and
29141591Ssklower  *  demultiplexes based on the logical channel number.
29241591Ssklower  *
29349930Ssklower  *  We change the original conventions of the UBC code here --
29449930Ssklower  *  since there may be multiple pkcb's for 802.2 class 2
29549930Ssklower  *  for a given interface, we must be informed which one it is;
29649930Ssklower  *  so we overwrite the pkthdr.rcvif; it can be recovered if necessary.
29749930Ssklower  *
29841591Ssklower  */
29941591Ssklower 
300*57024Ssklower #define RESTART_DTE_ORIGINATED(xp) (((xp) -> packet_cause == X25_RESTART_DTE_ORIGINATED) || \
301*57024Ssklower 			    ((xp) -> packet_cause >= X25_RESTART_DTE_ORIGINATED2))
302*57024Ssklower 
30349930Ssklower pk_input (m)
30441591Ssklower register struct mbuf *m;
30541591Ssklower {
30641591Ssklower 	register struct x25_packet *xp;
30741591Ssklower 	register struct pklcd *lcp;
30841591Ssklower 	register struct socket *so = 0;
30941591Ssklower 	register struct pkcb *pkp;
31041591Ssklower 	int  ptype, lcn, lcdstate = LISTEN;
31141591Ssklower 
31249593Ssklower 	if (pk_input_cache.mbc_size || pk_input_cache.mbc_oldsize)
31349593Ssklower 		mbuf_cache(&pk_input_cache, m);
31449930Ssklower 	if ((m->m_flags & M_PKTHDR) == 0)
31549930Ssklower 		panic("pkintr");
316*57024Ssklower 
31749930Ssklower 	if ((pkp = (struct pkcb *)m->m_pkthdr.rcvif) == 0)
31849930Ssklower 		return;
31941591Ssklower 	xp = mtod (m, struct x25_packet *);
32041591Ssklower 	ptype = pk_decode (xp);
32145573Ssklower 	lcn = LCN(xp);
32241591Ssklower 	lcp = pkp -> pk_chan[lcn];
32341591Ssklower 
32441591Ssklower 	/*
32541591Ssklower 	 *  If the DTE is in Restart  state, then it will ignore data,
32641591Ssklower 	 *  interrupt, call setup and clearing, flow control and reset
32741591Ssklower 	 *  packets.
32841591Ssklower 	 */
32941591Ssklower 	if (lcn < 0 || lcn > pkp -> pk_maxlcn) {
33041591Ssklower 		pk_message (lcn, pkp -> pk_xcp, "illegal lcn");
33141591Ssklower 		m_freem (m);
33241591Ssklower 		return;
33341591Ssklower 	}
33441591Ssklower 
33545895Ssklower 	pk_trace (pkp -> pk_xcp, m, "P-In");
33641591Ssklower 
33741591Ssklower 	if (pkp -> pk_state != DTE_READY && ptype != RESTART && ptype != RESTART_CONF) {
33841591Ssklower 		m_freem (m);
33941591Ssklower 		return;
34041591Ssklower 	}
34141591Ssklower 	if (lcp) {
34241591Ssklower 		so = lcp -> lcd_so;
34341591Ssklower 		lcdstate = lcp -> lcd_state;
34441591Ssklower 	} else {
34541591Ssklower 		if (ptype == CLEAR) {	/* idle line probe (Datapac specific) */
34641591Ssklower 			/* send response on lcd 0's output queue */
34749930Ssklower 			lcp = pkp -> pk_chan[0];
34841591Ssklower 			lcp -> lcd_template = pk_template (lcn, X25_CLEAR_CONFIRM);
34941591Ssklower 			pk_output (lcp);
35041591Ssklower 			m_freem (m);
35141591Ssklower 			return;
35241591Ssklower 		}
35341591Ssklower 		if (ptype != CALL)
35441591Ssklower 			ptype = INVALID_PACKET;
35541591Ssklower 	}
35641591Ssklower 
35741591Ssklower 	if (lcn == 0 && ptype != RESTART && ptype != RESTART_CONF) {
35845297Ssklower 		pk_message (0, pkp -> pk_xcp, "illegal ptype (%d, %s) on lcn 0",
35945297Ssklower 			ptype, pk_name[ptype / MAXSTATES]);
36045297Ssklower 		if (pk_bad_packet)
36145297Ssklower 			m_freem (pk_bad_packet);
36245297Ssklower 		pk_bad_packet = m;
36341591Ssklower 		return;
36441591Ssklower 	}
36541591Ssklower 
36641591Ssklower 	switch (ptype + lcdstate) {
36741591Ssklower 	/*
36841591Ssklower 	 *  Incoming Call packet received.
36941591Ssklower 	 */
37041591Ssklower 	case CALL + LISTEN:
37149593Ssklower 		pk_incoming_call (pkp, m);
37241591Ssklower 		break;
37341591Ssklower 
37441591Ssklower 	/*
37541591Ssklower 	 *  Call collision: Just throw this "incoming call" away since
37641591Ssklower 	 *  the DCE will ignore it anyway.
37741591Ssklower 	 */
37841591Ssklower 	case CALL + SENT_CALL:
37945573Ssklower 		pk_message ((int)lcn, pkp -> pk_xcp,
38041591Ssklower 			"incoming call collision");
38141591Ssklower 		break;
38241591Ssklower 
38341591Ssklower 	/*
38441591Ssklower 	 *  Call confirmation packet received. This usually means our
38541591Ssklower 	 *  previous connect request is now complete.
38641591Ssklower 	 */
38741591Ssklower 	case CALL_ACCEPTED + SENT_CALL:
38849252Ssklower 		MCHTYPE(m, MT_CONTROL);
38949593Ssklower 		pk_call_accepted (lcp, m);
39041591Ssklower 		break;
39141591Ssklower 
39241591Ssklower 	/*
39341591Ssklower 	 *  This condition can only happen if the previous state was
39441591Ssklower 	 *  SENT_CALL. Just ignore the packet, eventually a clear
39541591Ssklower 	 *  confirmation should arrive.
39641591Ssklower 	 */
39741591Ssklower 	case CALL_ACCEPTED + SENT_CLEAR:
39841591Ssklower 		break;
39941591Ssklower 
40041591Ssklower 	/*
40141591Ssklower 	 *  Clear packet received. This requires a complete tear down
40241591Ssklower 	 *  of the virtual circuit.  Free buffers and control blocks.
40341591Ssklower 	 *  and send a clear confirmation.
40441591Ssklower 	 */
40541591Ssklower 	case CLEAR + READY:
40641591Ssklower 	case CLEAR + RECEIVED_CALL:
40741591Ssklower 	case CLEAR + SENT_CALL:
40841591Ssklower 	case CLEAR + DATA_TRANSFER:
40941591Ssklower 		lcp -> lcd_state = RECEIVED_CLEAR;
41041591Ssklower 		lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CLEAR_CONFIRM);
41141591Ssklower 		pk_output (lcp);
41241591Ssklower 		pk_clearcause (pkp, xp);
41349252Ssklower 		if (lcp -> lcd_upper) {
41449252Ssklower 			MCHTYPE(m, MT_CONTROL);
41549252Ssklower 			lcp -> lcd_upper (lcp, m);
41649252Ssklower 		}
41741591Ssklower 		pk_close (lcp);
41849252Ssklower 		lcp = 0;
41941591Ssklower 		break;
42041591Ssklower 
42141591Ssklower 	/*
42241591Ssklower 	 *  Clear collision: Treat this clear packet as a confirmation.
42341591Ssklower 	 */
42441591Ssklower 	case CLEAR + SENT_CLEAR:
42541591Ssklower 		pk_close (lcp);
42641591Ssklower 		break;
42741591Ssklower 
42841591Ssklower 	/*
42941591Ssklower 	 *  Clear confirmation received. This usually means the virtual
43041591Ssklower 	 *  circuit is now completely removed.
43141591Ssklower 	 */
43241591Ssklower 	case CLEAR_CONF + SENT_CLEAR:
43341591Ssklower 		pk_close (lcp);
43441591Ssklower 		break;
43541591Ssklower 
43641591Ssklower 	/*
43741591Ssklower 	 *  A clear confirmation on an unassigned logical channel - just
43841591Ssklower 	 *  ignore it. Note: All other packets on an unassigned channel
43941591Ssklower 	 *  results in a clear.
44041591Ssklower 	 */
44141591Ssklower 	case CLEAR_CONF + READY:
44249930Ssklower 	case CLEAR_CONF + LISTEN:
44341591Ssklower 		break;
44441591Ssklower 
44541591Ssklower 	/*
44641591Ssklower 	 *  Data packet received. Pass on to next level. Move the Q and M
44741591Ssklower 	 *  bits into the data portion for the next level.
44841591Ssklower 	 */
44941591Ssklower 	case DATA + DATA_TRANSFER:
45041591Ssklower 		if (lcp -> lcd_reset_condition) {
45141591Ssklower 			ptype = DELETE_PACKET;
45241591Ssklower 			break;
45341591Ssklower 		}
45441591Ssklower 
45541591Ssklower 		/*
45641591Ssklower 		 *  Process the P(S) flow control information in this Data packet.
45741591Ssklower 		 *  Check that the packets arrive in the correct sequence and that
45841591Ssklower 		 *  they are within the "lcd_input_window". Input window rotation is
45941591Ssklower 		 *  initiated by the receive interface.
46041591Ssklower 		 */
46141591Ssklower 
46241591Ssklower 		if (PS(xp) != ((lcp -> lcd_rsn + 1) % MODULUS) ||
46341591Ssklower 			PS(xp) == ((lcp -> lcd_input_window + lcp->lcd_windowsize) % MODULUS)) {
46441591Ssklower 			m_freem (m);
46545895Ssklower 			pk_procerror (RESET, lcp, "p(s) flow control error", 1);
46641591Ssklower 			break;
46741591Ssklower 		}
46841591Ssklower 		lcp -> lcd_rsn = PS(xp);
46941591Ssklower 
47041591Ssklower 		if (pk_ack (lcp, PR(xp)) != PACKET_OK) {
47141591Ssklower 			m_freem (m);
47241591Ssklower 			break;
47341591Ssklower 		}
47445895Ssklower 		m -> m_data += PKHEADERLN;
47545895Ssklower 		m -> m_len -= PKHEADERLN;
47645895Ssklower 		m -> m_pkthdr.len -= PKHEADERLN;
47745895Ssklower 
47849930Ssklower 		lcp -> lcd_rxcnt++;
47945895Ssklower 		if (lcp -> lcd_flags & X25_MBS_HOLD) {
48045895Ssklower 			register struct mbuf *n = lcp -> lcd_cps;
48145895Ssklower 			int mbit = MBIT(xp);
48245895Ssklower 			octet q_and_d_bits;
48345895Ssklower 
48445895Ssklower 			if (n) {
48545895Ssklower 				n -> m_pkthdr.len += m -> m_pkthdr.len;
48645895Ssklower 				while (n -> m_next)
48745895Ssklower 					n = n -> m_next;
48845895Ssklower 				n -> m_next = m;
48945895Ssklower 				m = lcp -> lcd_cps;
49045895Ssklower 
49145895Ssklower 				if (lcp -> lcd_cpsmax &&
49245895Ssklower 				    n -> m_pkthdr.len > lcp -> lcd_cpsmax) {
49345895Ssklower 					pk_procerror (RESET, lcp,
49445895Ssklower 						"C.P.S. overflow", 128);
49545895Ssklower 					return;
49645895Ssklower 				}
49745895Ssklower 				q_and_d_bits = 0xc0 & *(octet *)xp;
49845895Ssklower 				xp = (struct x25_packet *)
49945895Ssklower 					(mtod(m, octet *) - PKHEADERLN);
50045895Ssklower 				*(octet *)xp |= q_and_d_bits;
50145895Ssklower 			}
50245895Ssklower 			if (mbit) {
50345895Ssklower 				lcp -> lcd_cps = m;
50447268Ssklower 				pk_flowcontrol(lcp, 0, 1);
50545895Ssklower 				return;
50645895Ssklower 			}
50745895Ssklower 			lcp -> lcd_cps = 0;
50845895Ssklower 		}
50945297Ssklower 		if (so == 0)
51045297Ssklower 			break;
51141591Ssklower 		if (lcp -> lcd_flags & X25_MQBIT) {
512*57024Ssklower 			octet t = (X25GBITS(xp -> bits, q_bit)) ? t = 0x80 : 0;
51341591Ssklower 
51445573Ssklower 			if (MBIT(xp))
51545573Ssklower 				t |= 0x40;
51643361Ssklower 			m -> m_data -= 1;
51741591Ssklower 			m -> m_len += 1;
51845895Ssklower 			m -> m_pkthdr.len += 1;
51945573Ssklower 			*mtod(m, octet *) = t;
52041591Ssklower 		}
52141591Ssklower 
52241591Ssklower 		/*
52341591Ssklower 		 * Discard Q-BIT packets if the application
52441591Ssklower 		 * doesn't want to be informed of M and Q bit status
52541591Ssklower 		 */
526*57024Ssklower 		if (X25GBITS(xp -> bits, q_bit)
527*57024Ssklower 		    && (lcp -> lcd_flags & X25_MQBIT) == 0) {
52841591Ssklower 			m_freem (m);
52941591Ssklower 			/*
53041591Ssklower 			 * NB.  This is dangerous: sending a RR here can
53141591Ssklower 			 * cause sequence number errors if a previous data
53241591Ssklower 			 * packet has not yet been passed up to the application
53341591Ssklower 			 * (RR's are normally generated via PRU_RCVD).
53441591Ssklower 			 */
53547268Ssklower 			pk_flowcontrol(lcp, 0, 1);
53641591Ssklower 		} else {
53741591Ssklower 			sbappendrecord (&so -> so_rcv, m);
53841591Ssklower 			sorwakeup (so);
53941591Ssklower 		}
54041591Ssklower 		break;
54141591Ssklower 
54241591Ssklower 	/*
54341591Ssklower 	 *  Interrupt packet received.
54441591Ssklower 	 */
54541591Ssklower 	case INTERRUPT + DATA_TRANSFER:
54641591Ssklower 		if (lcp -> lcd_reset_condition)
54741591Ssklower 			break;
54841591Ssklower 		lcp -> lcd_intrdata = xp -> packet_data;
54941591Ssklower 		lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM);
55041591Ssklower 		pk_output (lcp);
55145895Ssklower 		m -> m_data += PKHEADERLN;
55245895Ssklower 		m -> m_len -= PKHEADERLN;
55345895Ssklower 		m -> m_pkthdr.len -= PKHEADERLN;
55445297Ssklower 		MCHTYPE(m, MT_OOBDATA);
55545895Ssklower 		if (so) {
55645895Ssklower 			if (so -> so_options & SO_OOBINLINE)
55745895Ssklower 				sbinsertoob (&so -> so_rcv, m);
55845895Ssklower 			else
55945895Ssklower 				m_freem (m);
56045297Ssklower 			sohasoutofband (so);
56145895Ssklower 		}
56241591Ssklower 		break;
56341591Ssklower 
56441591Ssklower 	/*
56541591Ssklower 	 *  Interrupt confirmation packet received.
56641591Ssklower 	 */
56741591Ssklower 	case INTERRUPT_CONF + DATA_TRANSFER:
56841591Ssklower 		if (lcp -> lcd_reset_condition)
56941591Ssklower 			break;
57041591Ssklower 		if (lcp -> lcd_intrconf_pending == TRUE)
57141591Ssklower 			lcp -> lcd_intrconf_pending = FALSE;
57241591Ssklower 		else
57345895Ssklower 			pk_procerror (RESET, lcp, "unexpected packet", 43);
57441591Ssklower 		break;
57541591Ssklower 
57641591Ssklower 	/*
57741591Ssklower 	 *  Receiver ready received. Rotate the output window and output
57841591Ssklower 	 *  any data packets waiting transmission.
57941591Ssklower 	 */
58041591Ssklower 	case RR + DATA_TRANSFER:
58145297Ssklower 		if (lcp -> lcd_reset_condition ||
58245297Ssklower 		    pk_ack (lcp, PR(xp)) != PACKET_OK) {
58345297Ssklower 			ptype = DELETE_PACKET;
58441591Ssklower 			break;
58545297Ssklower 		}
58641591Ssklower 		if (lcp -> lcd_rnr_condition == TRUE)
58741591Ssklower 			lcp -> lcd_rnr_condition = FALSE;
58841591Ssklower 		pk_output (lcp);
58941591Ssklower 		break;
59041591Ssklower 
59141591Ssklower 	/*
59241591Ssklower 	 *  Receiver Not Ready received. Packets up to the P(R) can be
59341591Ssklower 	 *  be sent. Condition is cleared with a RR.
59441591Ssklower 	 */
59541591Ssklower 	case RNR + DATA_TRANSFER:
59645297Ssklower 		if (lcp -> lcd_reset_condition ||
59745297Ssklower 		    pk_ack (lcp, PR(xp)) != PACKET_OK) {
59845297Ssklower 			ptype = DELETE_PACKET;
59941591Ssklower 			break;
60045297Ssklower 		}
60141591Ssklower 		lcp -> lcd_rnr_condition = TRUE;
60241591Ssklower 		break;
60341591Ssklower 
60441591Ssklower 	/*
60541591Ssklower 	 *  Reset packet received. Set state to FLOW_OPEN.  The Input and
60641591Ssklower 	 *  Output window edges ar set to zero. Both the send and receive
60741591Ssklower 	 *  numbers are reset. A confirmation is returned.
60841591Ssklower 	 */
60941591Ssklower 	case RESET + DATA_TRANSFER:
61041591Ssklower 		if (lcp -> lcd_reset_condition)
61141591Ssklower 			/* Reset collision. Just ignore packet. */
61241591Ssklower 			break;
61341591Ssklower 
61441591Ssklower 		pk_resetcause (pkp, xp);
61541591Ssklower 		lcp -> lcd_window_condition = lcp -> lcd_rnr_condition =
61641591Ssklower 			lcp -> lcd_intrconf_pending = FALSE;
61741591Ssklower 		lcp -> lcd_output_window = lcp -> lcd_input_window =
61841591Ssklower 			lcp -> lcd_last_transmitted_pr = 0;
61941591Ssklower 		lcp -> lcd_ssn = 0;
62041591Ssklower 		lcp -> lcd_rsn = MODULUS - 1;
62141591Ssklower 
62241591Ssklower 		lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM);
62341591Ssklower 		pk_output (lcp);
62445297Ssklower 
62545895Ssklower 		pk_flush(lcp);
62645297Ssklower 		if (so == 0)
62745297Ssklower 			break;
62845297Ssklower 		wakeup ((caddr_t) & so -> so_timeo);
62945297Ssklower 		sorwakeup (so);
63045297Ssklower 		sowwakeup (so);
63141591Ssklower 		break;
63241591Ssklower 
63341591Ssklower 	/*
63441591Ssklower 	 *  Reset confirmation received.
63541591Ssklower 	 */
63641591Ssklower 	case RESET_CONF + DATA_TRANSFER:
63741591Ssklower 		if (lcp -> lcd_reset_condition) {
63841591Ssklower 			lcp -> lcd_reset_condition = FALSE;
63941591Ssklower 			pk_output (lcp);
64041591Ssklower 		}
64141591Ssklower 		else
64245895Ssklower 			pk_procerror (RESET, lcp, "unexpected packet", 32);
64341591Ssklower 		break;
64441591Ssklower 
64541591Ssklower 	case DATA + SENT_CLEAR:
64641591Ssklower 		ptype = DELETE_PACKET;
64741591Ssklower 	case RR + SENT_CLEAR:
64841591Ssklower 	case RNR + SENT_CLEAR:
64941591Ssklower 	case INTERRUPT + SENT_CLEAR:
65041591Ssklower 	case INTERRUPT_CONF + SENT_CLEAR:
65141591Ssklower 	case RESET + SENT_CLEAR:
65241591Ssklower 	case RESET_CONF + SENT_CLEAR:
65345297Ssklower 		/* Just ignore p if we have sent a CLEAR already.
65441591Ssklower 		   */
65541591Ssklower 		break;
65641591Ssklower 
65741591Ssklower 	/*
65841591Ssklower 	 *  Restart sets all the permanent virtual circuits to the "Data
65941591Ssklower 	 *  Transfer" stae and  all the switched virtual circuits to the
66041591Ssklower 	 *  "Ready" state.
66141591Ssklower 	 */
66241591Ssklower 	case RESTART + READY:
66341591Ssklower 		switch (pkp -> pk_state) {
66441591Ssklower 		case DTE_SENT_RESTART:
665*57024Ssklower 			/*
666*57024Ssklower 			 * Restart collision.
667*57024Ssklower 			 * If case the restart cause is "DTE originated" we
668*57024Ssklower 			 * have a DTE-DTE situation and are trying to resolve
669*57024Ssklower 			 * who is going to play DTE/DCE [ISO 8208:4.2-4.5]
670*57024Ssklower 			 */
671*57024Ssklower 			if (RESTART_DTE_ORIGINATED(xp)) {
672*57024Ssklower 				pk_restart (pkp, X25_RESTART_DTE_ORIGINATED);
673*57024Ssklower 				pk_message (0, pkp -> pk_xcp,
674*57024Ssklower 					    "RESTART collision");
675*57024Ssklower 				if ((pkp -> pk_restartcolls++) > MAXRESTARTCOLLISIONS) {
676*57024Ssklower 					pk_message (0, pkp -> pk_xcp,
677*57024Ssklower 						    "excessive RESTART collisions");
678*57024Ssklower 					pkp -> pk_restartcolls = 0;
679*57024Ssklower 				}
680*57024Ssklower 				break;
681*57024Ssklower 			}
68241591Ssklower 			pkp -> pk_state = DTE_READY;
683*57024Ssklower 			pkp -> pk_dxerole |= DTE_PLAYDTE;
684*57024Ssklower 			pkp -> pk_dxerole &= ~DTE_PLAYDCE;
68541591Ssklower 			pk_message (0, pkp -> pk_xcp,
68641591Ssklower 				"Packet level operational");
687*57024Ssklower 			pk_message (0, pkp -> pk_xcp,
688*57024Ssklower 				    "Assuming DTE role");
689*57024Ssklower 			if (pkp -> pk_dxerole & DTE_CONNECTPENDING)
690*57024Ssklower 				pk_callcomplete(pkp);
69141591Ssklower 			break;
69241591Ssklower 
69341591Ssklower 		default:
69441591Ssklower 			pk_restart (pkp, -1);
69541591Ssklower 			pk_restartcause (pkp, xp);
69641591Ssklower 			pkp -> pk_chan[0] -> lcd_template = pk_template (0,
69741591Ssklower 				X25_RESTART_CONFIRM);
69841591Ssklower 			pk_output (pkp -> pk_chan[0]);
699*57024Ssklower 			pkp -> pk_state = DTE_READY;
700*57024Ssklower 			pkp -> pk_dxerole |= RESTART_DTE_ORIGINATED(xp) ? DTE_PLAYDCE :
701*57024Ssklower 				DTE_PLAYDTE;
702*57024Ssklower 			if (pkp -> pk_dxerole & DTE_PLAYDTE) {
703*57024Ssklower 				pkp -> pk_dxerole &= ~DTE_PLAYDCE;
704*57024Ssklower 				pk_message (0, pkp -> pk_xcp,
705*57024Ssklower 					    "Assuming DTE role");
706*57024Ssklower 			} else {
707*57024Ssklower 				pkp -> pk_dxerole &= ~DTE_PLAYDTE;
708*57024Ssklower 				pk_message (0, pkp -> pk_xcp,
709*57024Ssklower 					 "Assuming DCE role");
710*57024Ssklower 			}
711*57024Ssklower 			if (pkp -> pk_dxerole & DTE_CONNECTPENDING)
712*57024Ssklower 				pk_callcomplete(pkp);
71341591Ssklower 		}
71441591Ssklower 		break;
71541591Ssklower 
71641591Ssklower 	/*
71741591Ssklower 	 *  Restart confirmation received. All logical channels are set
71841591Ssklower 	 *  to READY.
71941591Ssklower 	 */
72041591Ssklower 	case RESTART_CONF + READY:
72141591Ssklower 		switch (pkp -> pk_state) {
72241591Ssklower 		case DTE_SENT_RESTART:
72341591Ssklower 			pkp -> pk_state = DTE_READY;
724*57024Ssklower 			pkp -> pk_dxerole |= DTE_PLAYDTE;
725*57024Ssklower 			pkp -> pk_dxerole &= ~DTE_PLAYDCE;
72641591Ssklower 			pk_message (0, pkp -> pk_xcp,
727*57024Ssklower 				    "Packet level operational");
728*57024Ssklower 			pk_message (0, pkp-> pk_xcp,
729*57024Ssklower 				    "Assuming DTE role");
730*57024Ssklower 			if (pkp -> pk_dxerole & DTE_CONNECTPENDING)
731*57024Ssklower 				pk_callcomplete(pkp);
73241591Ssklower 			break;
73341591Ssklower 
73441591Ssklower 		default:
73541591Ssklower 			/* Restart local procedure error. */
73641591Ssklower 			pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR);
73741591Ssklower 			pkp -> pk_state = DTE_SENT_RESTART;
738*57024Ssklower 			pkp -> pk_dxerole &= ~(DTE_PLAYDTE | DTE_PLAYDCE);
73941591Ssklower 		}
74041591Ssklower 		break;
74141591Ssklower 
74241591Ssklower 	default:
74341591Ssklower 		if (lcp) {
74445895Ssklower 			pk_procerror (CLEAR, lcp, "unknown packet error", 33);
74541591Ssklower 			pk_message (lcn, pkp -> pk_xcp,
74641591Ssklower 				"\"%s\" unexpected in \"%s\" state",
74741591Ssklower 				pk_name[ptype/MAXSTATES], pk_state[lcdstate]);
74845895Ssklower 		} else
74945573Ssklower 			pk_message (lcn, pkp -> pk_xcp,
75041591Ssklower 				"packet arrived on unassigned lcn");
75141591Ssklower 		break;
75241591Ssklower 	}
75349252Ssklower 	if (so == 0 && lcp && lcp -> lcd_upper && lcdstate == DATA_TRANSFER) {
75445895Ssklower 		if (ptype != DATA && ptype != INTERRUPT)
75545895Ssklower 			MCHTYPE(m, MT_CONTROL);
75645297Ssklower 		lcp -> lcd_upper (lcp, m);
75745895Ssklower 	} else if (ptype != DATA && ptype != INTERRUPT)
75841591Ssklower 		m_freem (m);
75941591Ssklower }
76041591Ssklower 
76149930Ssklower static
76249930Ssklower prune_dnic(from, to, dnicname, xcp)
76349930Ssklower char *from, *to, *dnicname;
76449930Ssklower register struct x25config *xcp;
76549930Ssklower {
76649930Ssklower 	register char *cp1 = from, *cp2 = from;
76749930Ssklower 	if (xcp->xc_prepnd0 && *cp1 == '0') {
76849930Ssklower 		from = ++cp1;
76949930Ssklower 		goto copyrest;
77049930Ssklower 	}
77149930Ssklower 	if (xcp->xc_nodnic) {
77249930Ssklower 		for (cp1 = dnicname; *cp2 = *cp1++;)
77349930Ssklower 			cp2++;
77449930Ssklower 		cp1 = from;
77549930Ssklower 	}
77649930Ssklower copyrest:
77749930Ssklower 	for (cp1 = dnicname; *cp2 = *cp1++;)
77849930Ssklower 		cp2++;
77949930Ssklower }
78049930Ssklower /* static */
78149930Ssklower pk_simple_bsd (from, to, lower, len)
78249930Ssklower register octet *from, *to;
78349930Ssklower register len, lower;
78449930Ssklower {
78549930Ssklower 	register int c;
78649930Ssklower 	while (--len >= 0) {
78749930Ssklower 		c = *from;
78849930Ssklower 		if (lower & 0x01)
78949930Ssklower 			*from++;
79049930Ssklower 		else
79149930Ssklower 			c >>= 4;
79249930Ssklower 		c &= 0x0f; c |= 0x30; *to++ = c; lower++;
79349930Ssklower 	}
79449930Ssklower 	*to = 0;
79549930Ssklower }
79641591Ssklower 
79749930Ssklower /*static octet * */
79849930Ssklower pk_from_bcd (a, iscalling, sa, xcp)
79949930Ssklower register struct x25_calladdr *a;
80049930Ssklower register struct sockaddr_x25 *sa;
80149930Ssklower register struct x25config *xcp;
80249930Ssklower {
80349930Ssklower 	octet buf[MAXADDRLN+1];
80449930Ssklower 	octet *cp;
80549930Ssklower 	unsigned count;
80649930Ssklower 
80749930Ssklower 	bzero ((caddr_t)sa, sizeof (*sa));
80849930Ssklower 	sa -> x25_len = sizeof (*sa);
80949930Ssklower 	sa -> x25_family = AF_CCITT;
81049930Ssklower 	if (iscalling) {
811*57024Ssklower 		cp = a -> address_field + (X25GBITS(a -> addrlens, called_addrlen) / 2);
812*57024Ssklower 		count = X25GBITS(a -> addrlens, calling_addrlen);
813*57024Ssklower 		pk_simple_bsd (cp, buf, X25GBITS(a -> addrlens, called_addrlen), count);
81449930Ssklower 	} else {
815*57024Ssklower 		count = X25GBITS(a -> addrlens, called_addrlen);
81649930Ssklower 		pk_simple_bsd (a -> address_field, buf, 0, count);
81749930Ssklower 	}
81849930Ssklower 	if (xcp -> xc_addr.x25_net && (xcp -> xc_nodnic || xcp ->xc_prepnd0)) {
81949930Ssklower 		octet dnicname[sizeof(long) * NBBY/3 + 2];
82049930Ssklower 
821*57024Ssklower 		sprintf ((char *) dnicname, "%d", xcp -> xc_addr.x25_net);
822*57024Ssklower 		prune_dnic ((char *)buf, sa -> x25_addr, dnicname, xcp);
82349930Ssklower 	} else
82449930Ssklower 		bcopy ((caddr_t)buf, (caddr_t)sa -> x25_addr, count + 1);
82549930Ssklower }
82649930Ssklower 
82749930Ssklower static
82849930Ssklower save_extra(m0, fp, so)
82949930Ssklower struct mbuf *m0;
83049930Ssklower octet *fp;
83149930Ssklower struct socket *so;
83249930Ssklower {
83349930Ssklower 	register struct mbuf *m;
83449930Ssklower 	struct cmsghdr cmsghdr;
83552449Ssklower 	if (m = m_copy (m, 0, (int)M_COPYALL)) {
83649930Ssklower 		int off = fp - mtod (m0, octet *);
83749930Ssklower 		int len = m->m_pkthdr.len - off + sizeof (cmsghdr);
83849930Ssklower 		cmsghdr.cmsg_len = len;
83949930Ssklower 		cmsghdr.cmsg_level = AF_CCITT;
84049930Ssklower 		cmsghdr.cmsg_type = PK_FACILITIES;
84149930Ssklower 		m_adj (m, off);
84249930Ssklower 		M_PREPEND (m, sizeof(cmsghdr), M_DONTWAIT);
84349930Ssklower 		if (m == 0)
84449930Ssklower 			return;
84549930Ssklower 		bcopy ((caddr_t)&cmsghdr, mtod (m, caddr_t), sizeof (cmsghdr));
84649930Ssklower 		MCHTYPE(m, MT_CONTROL);
84749930Ssklower 		sbappendrecord(&so -> so_rcv, m);
84849930Ssklower 	}
84949930Ssklower }
85049930Ssklower 
85141591Ssklower /*
85241591Ssklower  * This routine handles incoming call packets. It matches the protocol
85341591Ssklower  * field on the Call User Data field (usually the first four bytes) with
85441591Ssklower  * sockets awaiting connections.
85541591Ssklower  */
85641591Ssklower 
85749593Ssklower pk_incoming_call (pkp, m0)
85845895Ssklower struct mbuf *m0;
85941591Ssklower struct pkcb *pkp;
86041591Ssklower {
86142277Ssklower 	register struct pklcd *lcp = 0, *l;
86241591Ssklower 	register struct sockaddr_x25 *sa;
86341591Ssklower 	register struct x25_calladdr *a;
86442277Ssklower 	register struct socket *so = 0;
86549930Ssklower 	struct	x25_packet *xp = mtod(m0, struct x25_packet *);
86649930Ssklower 	struct	mbuf *m;
86749930Ssklower 	struct	x25config *xcp = pkp -> pk_xcp;
86845895Ssklower 	int len = m0->m_pkthdr.len;
86949930Ssklower 	unsigned udlen;
87049930Ssklower 	char *errstr = "server unavailable";
87145895Ssklower 	octet *u, *facp;
87245573Ssklower 	int lcn = LCN(xp);
87341591Ssklower 
87449930Ssklower 	/* First, copy the data from the incoming call packet to a X25 address
87549930Ssklower 	   descriptor. It is to be regretted that you have
87649930Ssklower 	   to parse the facilities into a sockaddr to determine
87749930Ssklower 	   if reverse charging is being requested */
87849930Ssklower 	if ((m = m_get (M_DONTWAIT, MT_SONAME)) == 0)
87941591Ssklower 		return;
88041591Ssklower 	sa = mtod (m, struct sockaddr_x25 *);
88149930Ssklower 	a = (struct x25_calladdr *) &xp -> packet_data;
88249930Ssklower 	facp = u = (octet *) (a -> address_field +
883*57024Ssklower 		((X25GBITS(a -> addrlens, called_addrlen) + X25GBITS(a -> addrlens, calling_addrlen) + 1) / 2));
88449930Ssklower 	u += *u + 1;
88549930Ssklower 	udlen = min (16, ((octet *)xp) + len - u);
88649930Ssklower 	if (udlen < 0)
88749930Ssklower 		udlen = 0;
88849930Ssklower 	pk_from_bcd (a, 1, sa, pkp -> pk_xcp); /* get calling address */
88950426Ssklower 	pk_parse_facilities (facp, sa);
89049930Ssklower 	bcopy ((caddr_t)u, sa -> x25_udata, udlen);
89149930Ssklower 	sa -> x25_udlen = udlen;
89241591Ssklower 
89341591Ssklower 	/*
89450426Ssklower 	 * Now, loop through the listen sockets looking for a match on the
89550426Ssklower 	 * PID. That is the first few octets of the user data field.
89650426Ssklower 	 * This is the closest thing to a port number for X.25 packets.
89750426Ssklower 	 * It does provide a way of multiplexing services at the user level.
89841591Ssklower 	 */
89941591Ssklower 
90041591Ssklower 	for (l = pk_listenhead; l; l = l -> lcd_listen) {
90141591Ssklower 		struct sockaddr_x25 *sxp = l -> lcd_ceaddr;
90241591Ssklower 
90349930Ssklower 		if (bcmp (sxp -> x25_udata, u, sxp->x25_udlen))
90441591Ssklower 			continue;
90545165Ssklower 		if (sxp -> x25_net &&
90649930Ssklower 		    sxp -> x25_net != xcp -> xc_addr.x25_net)
90741591Ssklower 			continue;
90841591Ssklower 		/*
90949930Ssklower 		 * don't accept incoming calls with the D-Bit on
91049930Ssklower 		 * unless the server agrees
91149930Ssklower 		 */
912*57024Ssklower 		if (X25GBITS(xp -> bits, d_bit) && !(sxp -> x25_opts.op_flags & X25_DBIT)) {
91349930Ssklower 			errstr = "incoming D-Bit mismatch";
91449930Ssklower 			break;
91549930Ssklower 		}
91649930Ssklower 		/*
91741591Ssklower 		 * don't accept incoming collect calls unless
91841591Ssklower 		 * the server sets the reverse charging option.
91941591Ssklower 		 */
92041591Ssklower 		if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 &&
92141591Ssklower 			sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) {
92241591Ssklower 			errstr = "incoming collect call refused";
92341591Ssklower 			break;
92441591Ssklower 		}
92542277Ssklower 		if (l -> lcd_so) {
92645165Ssklower 			if (so = sonewconn (l -> lcd_so, SS_ISCONNECTED))
92742277Ssklower 				    lcp = (struct pklcd *) so -> so_pcb;
92842277Ssklower 		} else
92942277Ssklower 			lcp = pk_attach((struct socket *) 0);
93042277Ssklower 		if (lcp == 0) {
93141591Ssklower 			/*
93241591Ssklower 			 * Insufficient space or too many unaccepted
93341591Ssklower 			 * connections.  Just throw the call away.
93441591Ssklower 			 */
93541591Ssklower 			errstr = "server malfunction";
93641591Ssklower 			break;
93741591Ssklower 		}
93843361Ssklower 		lcp -> lcd_upper = l -> lcd_upper;
93943361Ssklower 		lcp -> lcd_upnext = l -> lcd_upnext;
94041591Ssklower 		lcp -> lcd_lcn = lcn;
94141591Ssklower 		lcp -> lcd_state = RECEIVED_CALL;
94250020Ssklower 		sa -> x25_opts.op_flags |= (sxp -> x25_opts.op_flags &
94350020Ssklower 			~X25_REVERSE_CHARGE) | l -> lcd_flags;
94441591Ssklower 		pk_assoc (pkp, lcp, sa);
94549930Ssklower 		lcp -> lcd_faddr = *sa;
94649930Ssklower 		lcp -> lcd_laddr.x25_udlen = sxp -> x25_udlen;
94749930Ssklower 		lcp -> lcd_craddr = &lcp->lcd_faddr;
94841591Ssklower 		lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED);
94945573Ssklower 		if (lcp -> lcd_flags & X25_DBIT) {
950*57024Ssklower 			if (X25GBITS(xp -> bits, d_bit))
951*57024Ssklower 				X25SBITS(mtod(lcp -> lcd_template,
952*57024Ssklower 					struct x25_packet *) -> bits, d_bit, 1);
95345573Ssklower 			else
95445573Ssklower 				lcp -> lcd_flags &= ~X25_DBIT;
95545573Ssklower 		}
95643361Ssklower 		if (so) {
95743361Ssklower 			pk_output (lcp);
95842277Ssklower 			soisconnected (so);
95945895Ssklower 			if (so -> so_options & SO_OOBINLINE)
96045895Ssklower 				save_extra(m0, facp, so);
96145895Ssklower 		} else if (lcp -> lcd_upper) {
96249930Ssklower 			(*lcp -> lcd_upper) (lcp, m0);
96345895Ssklower 		}
96449930Ssklower 		(void) m_free (m);
96541591Ssklower 		return;
96641591Ssklower 	}
96741591Ssklower 
96841591Ssklower 	/*
96941591Ssklower 	 * If the call fails for whatever reason, we still need to build a
97041591Ssklower 	 * skeleton LCD in order to be able to properly  receive the CLEAR
97141591Ssklower 	 * CONFIRMATION.
97241591Ssklower 	 */
97341591Ssklower #ifdef WATERLOO		/* be explicit */
97441591Ssklower 	if (l == 0 && bcmp(sa->x25_udata, "ean", 3) == 0)
97541591Ssklower 		pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s",
97641591Ssklower 			sa->x25_addr, sa->x25_udata[3] & 0xff, errstr);
97741591Ssklower 	else if (l == 0 && bcmp(sa->x25_udata, "\1\0\0\0", 4) == 0)
97841591Ssklower 		pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s",
97941591Ssklower 			sa->x25_addr, errstr);
98041591Ssklower 	else
98141591Ssklower #endif
98241591Ssklower 	pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s",
98341591Ssklower 		sa -> x25_addr, sa -> x25_udata[0] & 0xff,
98441591Ssklower 		sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff,
98541591Ssklower 		sa -> x25_udata[3] & 0xff, errstr);
98645297Ssklower 	if ((lcp = pk_attach((struct socket *)0)) == 0) {
98745297Ssklower 		(void) m_free (m);
98841591Ssklower 		return;
98941591Ssklower 	}
99041591Ssklower 	lcp -> lcd_lcn = lcn;
99141591Ssklower 	lcp -> lcd_state = RECEIVED_CALL;
99241591Ssklower 	pk_assoc (pkp, lcp, sa);
99345297Ssklower 	(void) m_free (m);
99445895Ssklower 	pk_clear (lcp, 0, 1);
99541591Ssklower }
99641591Ssklower 
99749593Ssklower pk_call_accepted (lcp, m)
99841591Ssklower struct pklcd *lcp;
99949252Ssklower struct mbuf *m;
100041591Ssklower {
100141591Ssklower 	register struct x25_calladdr *ap;
100241591Ssklower 	register octet *fcp;
100349252Ssklower 	struct x25_packet *xp = mtod (m, struct x25_packet *);
100449252Ssklower 	int len = m -> m_len;
100541591Ssklower 
100641591Ssklower 	lcp -> lcd_state = DATA_TRANSFER;
100745297Ssklower 	if (lcp -> lcd_so)
100845297Ssklower 		soisconnected (lcp -> lcd_so);
1009*57024Ssklower 	if ((lcp -> lcd_flags & X25_DBIT) && (X25GBITS(xp -> bits, d_bit) == 0))
101045573Ssklower 		lcp -> lcd_flags &= ~X25_DBIT;
101141591Ssklower 	if (len > 3) {
101241591Ssklower 		ap = (struct x25_calladdr *) &xp -> packet_data;
1013*57024Ssklower 		fcp = (octet *) ap -> address_field + (X25GBITS(ap -> addrlens, calling_addrlen) +
1014*57024Ssklower 			X25GBITS(ap -> addrlens, called_addrlen) + 1) / 2;
101541591Ssklower 		if (fcp + *fcp <= ((octet *)xp) + len)
101649593Ssklower 			pk_parse_facilities (fcp, lcp -> lcd_ceaddr);
101741591Ssklower 	}
101841591Ssklower 	pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr);
101949252Ssklower 	if (lcp -> lcd_so == 0 && lcp -> lcd_upper)
102049252Ssklower 		lcp -> lcd_upper(lcp, m);
102141591Ssklower }
102241591Ssklower 
102349593Ssklower pk_parse_facilities (fcp, sa)
102441591Ssklower register octet *fcp;
102541591Ssklower register struct sockaddr_x25 *sa;
102641591Ssklower {
102741591Ssklower 	register octet *maxfcp;
102841591Ssklower 
102941591Ssklower 	maxfcp = fcp + *fcp;
103041591Ssklower 	fcp++;
103141591Ssklower 	while (fcp < maxfcp) {
103241591Ssklower 		/*
103341591Ssklower 		 * Ignore national DCE or DTE facilities
103441591Ssklower 		 */
103541591Ssklower 		if (*fcp == 0 || *fcp == 0xff)
103641591Ssklower 			break;
103741591Ssklower 		switch (*fcp) {
103841591Ssklower 		case FACILITIES_WINDOWSIZE:
103941591Ssklower 			sa -> x25_opts.op_wsize = fcp[1];
104041591Ssklower 			fcp += 3;
104141591Ssklower 			break;
104241591Ssklower 
104341591Ssklower 		case FACILITIES_PACKETSIZE:
104441591Ssklower 			sa -> x25_opts.op_psize = fcp[1];
104541591Ssklower 			fcp += 3;
104641591Ssklower 			break;
104741591Ssklower 
104841591Ssklower 		case FACILITIES_THROUGHPUT:
104941591Ssklower 			sa -> x25_opts.op_speed = fcp[1];
105041591Ssklower 			fcp += 2;
105141591Ssklower 			break;
105241591Ssklower 
105341591Ssklower 		case FACILITIES_REVERSE_CHARGE:
105441591Ssklower 			if (fcp[1] & 01)
105541591Ssklower 				sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE;
105641591Ssklower 			/*
105741591Ssklower 			 * Datapac specific: for a X.25(1976) DTE, bit 2
105841591Ssklower 			 * indicates a "hi priority" (eg. international) call.
105941591Ssklower 			 */
106041591Ssklower 			if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0)
106141591Ssklower 				sa -> x25_opts.op_psize = X25_PS128;
106241591Ssklower 			fcp += 2;
106341591Ssklower 			break;
106441591Ssklower 
106541591Ssklower 		default:
106641591Ssklower /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/
106741591Ssklower 			switch ((*fcp & 0xc0) >> 6) {
106841591Ssklower 			case 0:			/* class A */
106941591Ssklower 				fcp += 2;
107041591Ssklower 				break;
107141591Ssklower 
107241591Ssklower 			case 1:
107341591Ssklower 				fcp += 3;
107441591Ssklower 				break;
107541591Ssklower 
107641591Ssklower 			case 2:
107741591Ssklower 				fcp += 4;
107841591Ssklower 				break;
107941591Ssklower 
108041591Ssklower 			case 3:
108141591Ssklower 				fcp++;
108241591Ssklower 				fcp += *fcp;
108341591Ssklower 			}
108441591Ssklower 		}
108541591Ssklower 	}
108641591Ssklower }
1087