This commit was manufactured by cvs2svn to create tag 'FreeBSD-release/1.0'.
[unix-history] / sys / netccitt / pk_input.c
CommitLineData
15637ed4
RG
1/*
2 * Copyright (c) University of British Columbia, 1984
3 * Copyright (c) 1991 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 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
78ed81a3 38 * from: @(#)pk_input.c 7.14 (Berkeley) 7/16/91
39 * $Id$
15637ed4
RG
40 */
41
42#include "param.h"
43#include "systm.h"
44#include "mbuf.h"
45#include "socket.h"
46#include "protosw.h"
47#include "socketvar.h"
48#include "errno.h"
49
50#include "../net/if.h"
51
52#include "x25.h"
53#include "pk.h"
54#include "pk_var.h"
55
56struct pkcb *
57pk_newlink (ia, llnext)
58struct x25_ifaddr *ia;
59caddr_t llnext;
60{
61 register struct x25config *xcp = &ia->ia_xc;
62 register struct pkcb *pkp;
63 register struct pklcd *lcp;
64 register struct protosw *pp;
65 unsigned size;
66
67 pp = pffindproto (AF_CCITT, (int)xcp -> xc_lproto, 0);
68 if (pp == 0 || pp -> pr_output == 0) {
69 pk_message (0, xcp, "link level protosw error");
70 return ((struct pkcb *)0);
71 }
72 /*
73 * Allocate a network control block structure
74 */
75 size = sizeof (struct pkcb);
76 pkp = (struct pkcb *)malloc(size, M_PCB, M_WAITOK);
77 if (pkp == 0)
78 return ((struct pkcb *)0);
79 bzero ((caddr_t)pkp, size);
80 pkp -> pk_lloutput = pp -> pr_output;
81 pkp -> pk_xcp = xcp;
82 pkp -> pk_ia = ia;
83 pkp -> pk_state = DTE_WAITING;
84 pkp -> pk_next = pkcbhead;
85 pkp -> pk_llnext = llnext;
86 pkcbhead = pkp;
87
88 /*
89 * set defaults
90 */
91
92 if (xcp -> xc_pwsize == 0)
93 xcp -> xc_pwsize = DEFAULT_WINDOW_SIZE;
94 if (xcp -> xc_psize == 0)
95 xcp -> xc_psize = X25_PS128;
96 /*
97 * Allocate logical channel descriptor vector
98 */
99
100 (void)pk_resize(pkp);
101 return (pkp);
102}
103
104pk_resize (pkp)
105register struct pkcb *pkp;
106{
107 struct pklcd *dev_lcp = 0;
108 struct x25config *xcp = pkp -> pk_xcp;
109 if (pkp -> pk_chan &&
110 (pkp -> pk_maxlcn != xcp -> xc_maxlcn)) {
111 pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
112 dev_lcp = pkp -> pk_chan[0];
113 free ((caddr_t)pkp -> pk_chan, M_IFADDR);
114 pkp -> pk_chan = 0;
115 }
116 if (pkp -> pk_chan == 0) {
117 unsigned size;
118 pkp -> pk_maxlcn = xcp -> xc_maxlcn;
119 size = (pkp -> pk_maxlcn + 1) * sizeof (struct pklcd *);
120 pkp -> pk_chan =
121 (struct pklcd **) malloc (size, M_IFADDR, M_WAITOK);
122 if (pkp -> pk_chan) {
123 bzero ((caddr_t)pkp -> pk_chan, size);
124 /*
125 * Allocate a logical channel descriptor for lcn 0
126 */
127 if (dev_lcp == 0 &&
128 (dev_lcp = pk_attach ((struct socket *)0)) == 0)
129 return (ENOBUFS);
130 dev_lcp -> lcd_state = READY;
131 dev_lcp -> lcd_pkp = pkp;
132 pkp -> pk_chan[0] = dev_lcp;
133 } else {
134 if (dev_lcp)
135 pk_close (dev_lcp);
136 return (ENOBUFS);
137 }
138 }
139 return 0;
140}
141
142/*
143 * This procedure is called by the link level whenever the link
144 * becomes operational, is reset, or when the link goes down.
145 */
146
147pk_ctlinput (code, pkp)
148register struct pkcb *pkp;
149{
150
151
152 switch (code) {
153 case PRC_LINKUP:
154 if (pkp -> pk_state == DTE_WAITING)
155 pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
156 break;
157
158 case PRC_LINKDOWN:
159 pk_restart (pkp, -1); /* Clear all active circuits */
160 pkp -> pk_state = DTE_WAITING;
161 break;
162
163 case PRC_LINKRESET:
164 pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
165 break;
166
167 }
168 return (0);
169}
170struct ifqueue pkintrq;
171/*
172 * This routine is called if there are semi-smart devices that do HDLC
173 * in hardware and want to queue the packet and call level 3 directly
174 */
175pkintr ()
176{
177 register struct mbuf *m;
178 register struct ifaddr *ifa;
179 register struct ifnet *ifp;
180 register int s;
181
182 for (;;) {
183 s = splimp ();
184 IF_DEQUEUE (&pkintrq, m);
185 splx (s);
186 if (m == 0)
187 break;
188 if (m->m_len < PKHEADERLN) {
189 printf ("pkintr: packet too short (len=%d)\n",
190 m->m_len);
191 m_freem (m);
192 continue;
193 }
194 pk_input(m);
195 }
196}
197struct mbuf *pk_bad_packet;
198struct mbuf_cache pk_input_cache = {0 };
199/*
200 * X.25 PACKET INPUT
201 *
202 * This procedure is called by a link level procedure whenever
203 * an information frame is received. It decodes the packet and
204 * demultiplexes based on the logical channel number.
205 *
206 * We change the original conventions of the UBC code here --
207 * since there may be multiple pkcb's for 802.2 class 2
208 * for a given interface, we must be informed which one it is;
209 * so we overwrite the pkthdr.rcvif; it can be recovered if necessary.
210 *
211 */
212
213pk_input (m)
214register struct mbuf *m;
215{
216 register struct x25_packet *xp;
217 register struct pklcd *lcp;
218 register struct socket *so = 0;
219 register struct pkcb *pkp;
220 int ptype, lcn, lcdstate = LISTEN;
221
222 if (pk_input_cache.mbc_size || pk_input_cache.mbc_oldsize)
223 mbuf_cache(&pk_input_cache, m);
224 if ((m->m_flags & M_PKTHDR) == 0)
225 panic("pkintr");
226 if ((pkp = (struct pkcb *)m->m_pkthdr.rcvif) == 0)
227 return;
228 xp = mtod (m, struct x25_packet *);
229 ptype = pk_decode (xp);
230 lcn = LCN(xp);
231 lcp = pkp -> pk_chan[lcn];
232
233 /*
234 * If the DTE is in Restart state, then it will ignore data,
235 * interrupt, call setup and clearing, flow control and reset
236 * packets.
237 */
238 if (lcn < 0 || lcn > pkp -> pk_maxlcn) {
239 pk_message (lcn, pkp -> pk_xcp, "illegal lcn");
240 m_freem (m);
241 return;
242 }
243
244 pk_trace (pkp -> pk_xcp, m, "P-In");
245
246 if (pkp -> pk_state != DTE_READY && ptype != RESTART && ptype != RESTART_CONF) {
247 m_freem (m);
248 return;
249 }
250 if (lcp) {
251 so = lcp -> lcd_so;
252 lcdstate = lcp -> lcd_state;
253 } else {
254 if (ptype == CLEAR) { /* idle line probe (Datapac specific) */
255 /* send response on lcd 0's output queue */
256 lcp = pkp -> pk_chan[0];
257 lcp -> lcd_template = pk_template (lcn, X25_CLEAR_CONFIRM);
258 pk_output (lcp);
259 m_freem (m);
260 return;
261 }
262 if (ptype != CALL)
263 ptype = INVALID_PACKET;
264 }
265
266 if (lcn == 0 && ptype != RESTART && ptype != RESTART_CONF) {
267 pk_message (0, pkp -> pk_xcp, "illegal ptype (%d, %s) on lcn 0",
268 ptype, pk_name[ptype / MAXSTATES]);
269 if (pk_bad_packet)
270 m_freem (pk_bad_packet);
271 pk_bad_packet = m;
272 return;
273 }
274
275 switch (ptype + lcdstate) {
276 /*
277 * Incoming Call packet received.
278 */
279 case CALL + LISTEN:
280 pk_incoming_call (pkp, m);
281 break;
282
283 /*
284 * Call collision: Just throw this "incoming call" away since
285 * the DCE will ignore it anyway.
286 */
287 case CALL + SENT_CALL:
288 pk_message ((int)lcn, pkp -> pk_xcp,
289 "incoming call collision");
290 break;
291
292 /*
293 * Call confirmation packet received. This usually means our
294 * previous connect request is now complete.
295 */
296 case CALL_ACCEPTED + SENT_CALL:
297 MCHTYPE(m, MT_CONTROL);
298 pk_call_accepted (lcp, m);
299 break;
300
301 /*
302 * This condition can only happen if the previous state was
303 * SENT_CALL. Just ignore the packet, eventually a clear
304 * confirmation should arrive.
305 */
306 case CALL_ACCEPTED + SENT_CLEAR:
307 break;
308
309 /*
310 * Clear packet received. This requires a complete tear down
311 * of the virtual circuit. Free buffers and control blocks.
312 * and send a clear confirmation.
313 */
314 case CLEAR + READY:
315 case CLEAR + RECEIVED_CALL:
316 case CLEAR + SENT_CALL:
317 case CLEAR + DATA_TRANSFER:
318 lcp -> lcd_state = RECEIVED_CLEAR;
319 lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CLEAR_CONFIRM);
320 pk_output (lcp);
321 pk_clearcause (pkp, xp);
322 if (lcp -> lcd_upper) {
323 MCHTYPE(m, MT_CONTROL);
324 lcp -> lcd_upper (lcp, m);
325 }
326 pk_close (lcp);
327 lcp = 0;
328 break;
329
330 /*
331 * Clear collision: Treat this clear packet as a confirmation.
332 */
333 case CLEAR + SENT_CLEAR:
334 pk_close (lcp);
335 break;
336
337 /*
338 * Clear confirmation received. This usually means the virtual
339 * circuit is now completely removed.
340 */
341 case CLEAR_CONF + SENT_CLEAR:
342 pk_close (lcp);
343 break;
344
345 /*
346 * A clear confirmation on an unassigned logical channel - just
347 * ignore it. Note: All other packets on an unassigned channel
348 * results in a clear.
349 */
350 case CLEAR_CONF + READY:
351 case CLEAR_CONF + LISTEN:
352 break;
353
354 /*
355 * Data packet received. Pass on to next level. Move the Q and M
356 * bits into the data portion for the next level.
357 */
358 case DATA + DATA_TRANSFER:
359 if (lcp -> lcd_reset_condition) {
360 ptype = DELETE_PACKET;
361 break;
362 }
363
364 /*
365 * Process the P(S) flow control information in this Data packet.
366 * Check that the packets arrive in the correct sequence and that
367 * they are within the "lcd_input_window". Input window rotation is
368 * initiated by the receive interface.
369 */
370
371 if (PS(xp) != ((lcp -> lcd_rsn + 1) % MODULUS) ||
372 PS(xp) == ((lcp -> lcd_input_window + lcp->lcd_windowsize) % MODULUS)) {
373 m_freem (m);
374 pk_procerror (RESET, lcp, "p(s) flow control error", 1);
375 break;
376 }
377 lcp -> lcd_rsn = PS(xp);
378
379 if (pk_ack (lcp, PR(xp)) != PACKET_OK) {
380 m_freem (m);
381 break;
382 }
383 m -> m_data += PKHEADERLN;
384 m -> m_len -= PKHEADERLN;
385 m -> m_pkthdr.len -= PKHEADERLN;
386
387 lcp -> lcd_rxcnt++;
388 if (lcp -> lcd_flags & X25_MBS_HOLD) {
389 register struct mbuf *n = lcp -> lcd_cps;
390 int mbit = MBIT(xp);
391 octet q_and_d_bits;
392
393 if (n) {
394 n -> m_pkthdr.len += m -> m_pkthdr.len;
395 while (n -> m_next)
396 n = n -> m_next;
397 n -> m_next = m;
398 m = lcp -> lcd_cps;
399
400 if (lcp -> lcd_cpsmax &&
401 n -> m_pkthdr.len > lcp -> lcd_cpsmax) {
402 pk_procerror (RESET, lcp,
403 "C.P.S. overflow", 128);
404 return;
405 }
406 q_and_d_bits = 0xc0 & *(octet *)xp;
407 xp = (struct x25_packet *)
408 (mtod(m, octet *) - PKHEADERLN);
409 *(octet *)xp |= q_and_d_bits;
410 }
411 if (mbit) {
412 lcp -> lcd_cps = m;
413 pk_flowcontrol(lcp, 0, 1);
414 return;
415 }
416 lcp -> lcd_cps = 0;
417 }
418 if (so == 0)
419 break;
420 if (lcp -> lcd_flags & X25_MQBIT) {
421 octet t = (xp -> q_bit) ? t = 0x80 : 0;
422
423 if (MBIT(xp))
424 t |= 0x40;
425 m -> m_data -= 1;
426 m -> m_len += 1;
427 m -> m_pkthdr.len += 1;
428 *mtod(m, octet *) = t;
429 }
430
431 /*
432 * Discard Q-BIT packets if the application
433 * doesn't want to be informed of M and Q bit status
434 */
435 if (xp -> q_bit && (lcp -> lcd_flags & X25_MQBIT) == 0) {
436 m_freem (m);
437 /*
438 * NB. This is dangerous: sending a RR here can
439 * cause sequence number errors if a previous data
440 * packet has not yet been passed up to the application
441 * (RR's are normally generated via PRU_RCVD).
442 */
443 pk_flowcontrol(lcp, 0, 1);
444 } else {
445 sbappendrecord (&so -> so_rcv, m);
446 sorwakeup (so);
447 }
448 break;
449
450 /*
451 * Interrupt packet received.
452 */
453 case INTERRUPT + DATA_TRANSFER:
454 if (lcp -> lcd_reset_condition)
455 break;
456 lcp -> lcd_intrdata = xp -> packet_data;
457 lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM);
458 pk_output (lcp);
459 m -> m_data += PKHEADERLN;
460 m -> m_len -= PKHEADERLN;
461 m -> m_pkthdr.len -= PKHEADERLN;
462 MCHTYPE(m, MT_OOBDATA);
463 if (so) {
464 if (so -> so_options & SO_OOBINLINE)
465 sbinsertoob (&so -> so_rcv, m);
466 else
467 m_freem (m);
468 sohasoutofband (so);
469 }
470 break;
471
472 /*
473 * Interrupt confirmation packet received.
474 */
475 case INTERRUPT_CONF + DATA_TRANSFER:
476 if (lcp -> lcd_reset_condition)
477 break;
478 if (lcp -> lcd_intrconf_pending == TRUE)
479 lcp -> lcd_intrconf_pending = FALSE;
480 else
481 pk_procerror (RESET, lcp, "unexpected packet", 43);
482 break;
483
484 /*
485 * Receiver ready received. Rotate the output window and output
486 * any data packets waiting transmission.
487 */
488 case RR + DATA_TRANSFER:
489 if (lcp -> lcd_reset_condition ||
490 pk_ack (lcp, PR(xp)) != PACKET_OK) {
491 ptype = DELETE_PACKET;
492 break;
493 }
494 if (lcp -> lcd_rnr_condition == TRUE)
495 lcp -> lcd_rnr_condition = FALSE;
496 pk_output (lcp);
497 break;
498
499 /*
500 * Receiver Not Ready received. Packets up to the P(R) can be
501 * be sent. Condition is cleared with a RR.
502 */
503 case RNR + DATA_TRANSFER:
504 if (lcp -> lcd_reset_condition ||
505 pk_ack (lcp, PR(xp)) != PACKET_OK) {
506 ptype = DELETE_PACKET;
507 break;
508 }
509 lcp -> lcd_rnr_condition = TRUE;
510 break;
511
512 /*
513 * Reset packet received. Set state to FLOW_OPEN. The Input and
514 * Output window edges ar set to zero. Both the send and receive
515 * numbers are reset. A confirmation is returned.
516 */
517 case RESET + DATA_TRANSFER:
518 if (lcp -> lcd_reset_condition)
519 /* Reset collision. Just ignore packet. */
520 break;
521
522 pk_resetcause (pkp, xp);
523 lcp -> lcd_window_condition = lcp -> lcd_rnr_condition =
524 lcp -> lcd_intrconf_pending = FALSE;
525 lcp -> lcd_output_window = lcp -> lcd_input_window =
526 lcp -> lcd_last_transmitted_pr = 0;
527 lcp -> lcd_ssn = 0;
528 lcp -> lcd_rsn = MODULUS - 1;
529
530 lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM);
531 pk_output (lcp);
532
533 pk_flush(lcp);
534 if (so == 0)
535 break;
536 wakeup ((caddr_t) & so -> so_timeo);
537 sorwakeup (so);
538 sowwakeup (so);
539 break;
540
541 /*
542 * Reset confirmation received.
543 */
544 case RESET_CONF + DATA_TRANSFER:
545 if (lcp -> lcd_reset_condition) {
546 lcp -> lcd_reset_condition = FALSE;
547 pk_output (lcp);
548 }
549 else
550 pk_procerror (RESET, lcp, "unexpected packet", 32);
551 break;
552
553 case DATA + SENT_CLEAR:
554 ptype = DELETE_PACKET;
555 case RR + SENT_CLEAR:
556 case RNR + SENT_CLEAR:
557 case INTERRUPT + SENT_CLEAR:
558 case INTERRUPT_CONF + SENT_CLEAR:
559 case RESET + SENT_CLEAR:
560 case RESET_CONF + SENT_CLEAR:
561 /* Just ignore p if we have sent a CLEAR already.
562 */
563 break;
564
565 /*
566 * Restart sets all the permanent virtual circuits to the "Data
567 * Transfer" stae and all the switched virtual circuits to the
568 * "Ready" state.
569 */
570 case RESTART + READY:
571 switch (pkp -> pk_state) {
572 case DTE_SENT_RESTART:
573 /* Restart collision. */
574 pkp -> pk_state = DTE_READY;
575 pk_message (0, pkp -> pk_xcp,
576 "Packet level operational");
577 break;
578
579 default:
580 pk_restart (pkp, -1);
581 pk_restartcause (pkp, xp);
582 pkp -> pk_chan[0] -> lcd_template = pk_template (0,
583 X25_RESTART_CONFIRM);
584 pk_output (pkp -> pk_chan[0]);
585 }
586 break;
587
588 /*
589 * Restart confirmation received. All logical channels are set
590 * to READY.
591 */
592 case RESTART_CONF + READY:
593 switch (pkp -> pk_state) {
594 case DTE_SENT_RESTART:
595 pkp -> pk_state = DTE_READY;
596 pk_message (0, pkp -> pk_xcp,
597 "Packet level operational");
598 break;
599
600 default:
601 /* Restart local procedure error. */
602 pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR);
603 pkp -> pk_state = DTE_SENT_RESTART;
604 }
605 break;
606
607 default:
608 if (lcp) {
609 pk_procerror (CLEAR, lcp, "unknown packet error", 33);
610 pk_message (lcn, pkp -> pk_xcp,
611 "\"%s\" unexpected in \"%s\" state",
612 pk_name[ptype/MAXSTATES], pk_state[lcdstate]);
613 } else
614 pk_message (lcn, pkp -> pk_xcp,
615 "packet arrived on unassigned lcn");
616 break;
617 }
618 if (so == 0 && lcp && lcp -> lcd_upper && lcdstate == DATA_TRANSFER) {
619 if (ptype != DATA && ptype != INTERRUPT)
620 MCHTYPE(m, MT_CONTROL);
621 lcp -> lcd_upper (lcp, m);
622 } else if (ptype != DATA && ptype != INTERRUPT)
623 m_freem (m);
624}
625
626static
627prune_dnic(from, to, dnicname, xcp)
628char *from, *to, *dnicname;
629register struct x25config *xcp;
630{
631 register char *cp1 = from, *cp2 = from;
632 if (xcp->xc_prepnd0 && *cp1 == '0') {
633 from = ++cp1;
634 goto copyrest;
635 }
636 if (xcp->xc_nodnic) {
637 for (cp1 = dnicname; *cp2 = *cp1++;)
638 cp2++;
639 cp1 = from;
640 }
641copyrest:
642 for (cp1 = dnicname; *cp2 = *cp1++;)
643 cp2++;
644}
645/* static */
646pk_simple_bsd (from, to, lower, len)
647register octet *from, *to;
648register len, lower;
649{
650 register int c;
651 while (--len >= 0) {
652 c = *from;
653 if (lower & 0x01)
654 *from++;
655 else
656 c >>= 4;
657 c &= 0x0f; c |= 0x30; *to++ = c; lower++;
658 }
659 *to = 0;
660}
661
662/*static octet * */
663pk_from_bcd (a, iscalling, sa, xcp)
664register struct x25_calladdr *a;
665register struct sockaddr_x25 *sa;
666register struct x25config *xcp;
667{
668 octet buf[MAXADDRLN+1];
669 octet *cp;
670 unsigned count;
671
672 bzero ((caddr_t)sa, sizeof (*sa));
673 sa -> x25_len = sizeof (*sa);
674 sa -> x25_family = AF_CCITT;
675 if (iscalling) {
676 cp = a -> address_field + (a -> called_addrlen / 2);
677 count = a -> calling_addrlen;
678 pk_simple_bsd (cp, buf, a -> called_addrlen, count);
679 } else {
680 count = a -> called_addrlen;
681 pk_simple_bsd (a -> address_field, buf, 0, count);
682 }
683 if (xcp -> xc_addr.x25_net && (xcp -> xc_nodnic || xcp ->xc_prepnd0)) {
684 octet dnicname[sizeof(long) * NBBY/3 + 2];
685
686 sprintf (dnicname, "%d", xcp -> xc_addr.x25_net);
687 prune_dnic (buf, sa -> x25_addr, dnicname, xcp);
688 } else
689 bcopy ((caddr_t)buf, (caddr_t)sa -> x25_addr, count + 1);
690}
691
692static
693save_extra(m0, fp, so)
694struct mbuf *m0;
695octet *fp;
696struct socket *so;
697{
698 register struct mbuf *m;
699 struct cmsghdr cmsghdr;
700 if (m = m_copym (m, 0, (int)M_COPYALL)) {
701 int off = fp - mtod (m0, octet *);
702 int len = m->m_pkthdr.len - off + sizeof (cmsghdr);
703 cmsghdr.cmsg_len = len;
704 cmsghdr.cmsg_level = AF_CCITT;
705 cmsghdr.cmsg_type = PK_FACILITIES;
706 m_adj (m, off);
707 M_PREPEND (m, sizeof(cmsghdr), M_DONTWAIT);
708 if (m == 0)
709 return;
710 bcopy ((caddr_t)&cmsghdr, mtod (m, caddr_t), sizeof (cmsghdr));
711 MCHTYPE(m, MT_CONTROL);
712 sbappendrecord(&so -> so_rcv, m);
713 }
714}
715
716/*
717 * This routine handles incoming call packets. It matches the protocol
718 * field on the Call User Data field (usually the first four bytes) with
719 * sockets awaiting connections.
720 */
721
722pk_incoming_call (pkp, m0)
723struct mbuf *m0;
724struct pkcb *pkp;
725{
726 register struct pklcd *lcp = 0, *l;
727 register struct sockaddr_x25 *sa;
728 register struct x25_calladdr *a;
729 register struct socket *so = 0;
730 struct x25_packet *xp = mtod(m0, struct x25_packet *);
731 struct mbuf *m;
732 struct x25config *xcp = pkp -> pk_xcp;
733 int len = m0->m_pkthdr.len;
734 unsigned udlen;
735 char *errstr = "server unavailable";
736 octet *u, *facp;
737 int lcn = LCN(xp);
738
739 /* First, copy the data from the incoming call packet to a X25 address
740 descriptor. It is to be regretted that you have
741 to parse the facilities into a sockaddr to determine
742 if reverse charging is being requested */
743 if ((m = m_get (M_DONTWAIT, MT_SONAME)) == 0)
744 return;
745 sa = mtod (m, struct sockaddr_x25 *);
746 a = (struct x25_calladdr *) &xp -> packet_data;
747 facp = u = (octet *) (a -> address_field +
748 ((a -> called_addrlen + a -> calling_addrlen + 1) / 2));
749 u += *u + 1;
750 udlen = min (16, ((octet *)xp) + len - u);
751 if (udlen < 0)
752 udlen = 0;
753 pk_from_bcd (a, 1, sa, pkp -> pk_xcp); /* get calling address */
754 pk_parse_facilities (facp, sa);
755 bcopy ((caddr_t)u, sa -> x25_udata, udlen);
756 sa -> x25_udlen = udlen;
757
758 /*
759 * Now, loop through the listen sockets looking for a match on the
760 * PID. That is the first few octets of the user data field.
761 * This is the closest thing to a port number for X.25 packets.
762 * It does provide a way of multiplexing services at the user level.
763 */
764
765 for (l = pk_listenhead; l; l = l -> lcd_listen) {
766 struct sockaddr_x25 *sxp = l -> lcd_ceaddr;
767
768 if (bcmp (sxp -> x25_udata, u, sxp->x25_udlen))
769 continue;
770 if (sxp -> x25_net &&
771 sxp -> x25_net != xcp -> xc_addr.x25_net)
772 continue;
773 /*
774 * don't accept incoming calls with the D-Bit on
775 * unless the server agrees
776 */
777 if (xp -> d_bit && !(sxp -> x25_opts.op_flags & X25_DBIT)) {
778 errstr = "incoming D-Bit mismatch";
779 break;
780 }
781 /*
782 * don't accept incoming collect calls unless
783 * the server sets the reverse charging option.
784 */
785 if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 &&
786 sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) {
787 errstr = "incoming collect call refused";
788 break;
789 }
790 if (l -> lcd_so) {
791 if (so = sonewconn (l -> lcd_so, SS_ISCONNECTED))
792 lcp = (struct pklcd *) so -> so_pcb;
793 } else
794 lcp = pk_attach((struct socket *) 0);
795 if (lcp == 0) {
796 /*
797 * Insufficient space or too many unaccepted
798 * connections. Just throw the call away.
799 */
800 errstr = "server malfunction";
801 break;
802 }
803 lcp -> lcd_upper = l -> lcd_upper;
804 lcp -> lcd_upnext = l -> lcd_upnext;
805 lcp -> lcd_lcn = lcn;
806 lcp -> lcd_state = RECEIVED_CALL;
807 sa -> x25_opts.op_flags |= (sxp -> x25_opts.op_flags &
808 ~X25_REVERSE_CHARGE) | l -> lcd_flags;
809 pk_assoc (pkp, lcp, sa);
810 lcp -> lcd_faddr = *sa;
811 lcp -> lcd_laddr.x25_udlen = sxp -> x25_udlen;
812 lcp -> lcd_craddr = &lcp->lcd_faddr;
813 lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED);
814 if (lcp -> lcd_flags & X25_DBIT) {
815 if (xp -> d_bit)
816 mtod(lcp -> lcd_template,
817 struct x25_packet *) -> d_bit = 1;
818 else
819 lcp -> lcd_flags &= ~X25_DBIT;
820 }
821 if (so) {
822 pk_output (lcp);
823 soisconnected (so);
824 if (so -> so_options & SO_OOBINLINE)
825 save_extra(m0, facp, so);
826 } else if (lcp -> lcd_upper) {
827 (*lcp -> lcd_upper) (lcp, m0);
828 }
829 (void) m_free (m);
830 return;
831 }
832
833 /*
834 * If the call fails for whatever reason, we still need to build a
835 * skeleton LCD in order to be able to properly receive the CLEAR
836 * CONFIRMATION.
837 */
838#ifdef WATERLOO /* be explicit */
839 if (l == 0 && bcmp(sa->x25_udata, "ean", 3) == 0)
840 pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s",
841 sa->x25_addr, sa->x25_udata[3] & 0xff, errstr);
842 else if (l == 0 && bcmp(sa->x25_udata, "\1\0\0\0", 4) == 0)
843 pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s",
844 sa->x25_addr, errstr);
845 else
846#endif
847 pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s",
848 sa -> x25_addr, sa -> x25_udata[0] & 0xff,
849 sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff,
850 sa -> x25_udata[3] & 0xff, errstr);
851 if ((lcp = pk_attach((struct socket *)0)) == 0) {
852 (void) m_free (m);
853 return;
854 }
855 lcp -> lcd_lcn = lcn;
856 lcp -> lcd_state = RECEIVED_CALL;
857 pk_assoc (pkp, lcp, sa);
858 (void) m_free (m);
859 pk_clear (lcp, 0, 1);
860}
861
862pk_call_accepted (lcp, m)
863struct pklcd *lcp;
864struct mbuf *m;
865{
866 register struct x25_calladdr *ap;
867 register octet *fcp;
868 struct x25_packet *xp = mtod (m, struct x25_packet *);
869 int len = m -> m_len;
870
871 lcp -> lcd_state = DATA_TRANSFER;
872 if (lcp -> lcd_so)
873 soisconnected (lcp -> lcd_so);
874 if ((lcp -> lcd_flags & X25_DBIT) && (xp -> d_bit == 0))
875 lcp -> lcd_flags &= ~X25_DBIT;
876 if (len > 3) {
877 ap = (struct x25_calladdr *) &xp -> packet_data;
878 fcp = (octet *) ap -> address_field + (ap -> calling_addrlen +
879 ap -> called_addrlen + 1) / 2;
880 if (fcp + *fcp <= ((octet *)xp) + len)
881 pk_parse_facilities (fcp, lcp -> lcd_ceaddr);
882 }
883 pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr);
884 if (lcp -> lcd_so == 0 && lcp -> lcd_upper)
885 lcp -> lcd_upper(lcp, m);
886}
887
888pk_parse_facilities (fcp, sa)
889register octet *fcp;
890register struct sockaddr_x25 *sa;
891{
892 register octet *maxfcp;
893
894 maxfcp = fcp + *fcp;
895 fcp++;
896 while (fcp < maxfcp) {
897 /*
898 * Ignore national DCE or DTE facilities
899 */
900 if (*fcp == 0 || *fcp == 0xff)
901 break;
902 switch (*fcp) {
903 case FACILITIES_WINDOWSIZE:
904 sa -> x25_opts.op_wsize = fcp[1];
905 fcp += 3;
906 break;
907
908 case FACILITIES_PACKETSIZE:
909 sa -> x25_opts.op_psize = fcp[1];
910 fcp += 3;
911 break;
912
913 case FACILITIES_THROUGHPUT:
914 sa -> x25_opts.op_speed = fcp[1];
915 fcp += 2;
916 break;
917
918 case FACILITIES_REVERSE_CHARGE:
919 if (fcp[1] & 01)
920 sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE;
921 /*
922 * Datapac specific: for a X.25(1976) DTE, bit 2
923 * indicates a "hi priority" (eg. international) call.
924 */
925 if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0)
926 sa -> x25_opts.op_psize = X25_PS128;
927 fcp += 2;
928 break;
929
930 default:
931/*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/
932 switch ((*fcp & 0xc0) >> 6) {
933 case 0: /* class A */
934 fcp += 2;
935 break;
936
937 case 1:
938 fcp += 3;
939 break;
940
941 case 2:
942 fcp += 4;
943 break;
944
945 case 3:
946 fcp++;
947 fcp += *fcp;
948 }
949 }
950 }
951}