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