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