2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) University of British Columbia, 1984
24 * Copyright (C) Computer Science Department IV,
25 * University of Erlangen-Nuremberg, Germany, 1992
26 * Copyright (c) 1991, 1992, 1993
27 * The Regents of the University of California. All rights reserved.
29 * This code is derived from software contributed to Berkeley by the
30 * Laboratory for Computation Vision and the Computer Science Department
31 * of the the University of British Columbia and the Computer Science
32 * Department (IV) of the University of Erlangen-Nuremberg, Germany.
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
37 * 1. Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 * 2. Redistributions in binary form must reproduce the above copyright
40 * notice, this list of conditions and the following disclaimer in the
41 * documentation and/or other materials provided with the distribution.
42 * 3. All advertising materials mentioning features or use of this software
43 * must display the following acknowledgement:
44 * This product includes software developed by the University of
45 * California, Berkeley and its contributors.
46 * 4. Neither the name of the University nor the names of its contributors
47 * may be used to endorse or promote products derived from this software
48 * without specific prior written permission.
50 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * @(#)pk_input.c 8.1 (Berkeley) 6/10/93
65 #include <sys/param.h>
66 #include <sys/systm.h>
68 #include <sys/socket.h>
69 #include <sys/protosw.h>
70 #include <sys/socketvar.h>
71 #include <sys/errno.h>
72 #include <sys/malloc.h>
75 #include <net/if_dl.h>
76 #include <net/if_llc.h>
77 #include <net/route.h>
79 #include <netccitt/dll.h>
80 #include <netccitt/x25.h>
81 #include <netccitt/pk.h>
82 #include <netccitt/pk_var.h>
83 #include <netccitt/llc_var.h>
85 struct pkcb_q pkcb_q
= {&pkcb_q
, &pkcb_q
};
88 * ccittintr() is the generic interrupt handler for HDLC, LLC2, and X.25. This
89 * allows to have kernel running X.25 but no HDLC or LLC2 or both (in case we
90 * employ boards that do all the stuff themselves, e.g. ADAX X.25 or TPS ISDN.)
95 extern struct ifqueue pkintrq
;
96 extern struct ifqueue hdintrq
;
97 extern struct ifqueue llcintrq
;
104 if (llcintrq
.ifq_len
)
112 pk_newlink (ia
, llnext
)
113 struct x25_ifaddr
*ia
;
116 register struct x25config
*xcp
= &ia
-> ia_xc
;
117 register struct pkcb
*pkp
;
118 register struct pklcd
*lcp
;
119 register struct protosw
*pp
;
122 pp
= pffindproto (AF_CCITT
, (int) xcp
-> xc_lproto
, 0);
123 if (pp
== 0 || pp
-> pr_output
== 0) {
124 pk_message (0, xcp
, "link level protosw error");
125 return ((struct pkcb
*)0);
128 * Allocate a network control block structure
130 size
= sizeof (struct pkcb
);
131 // pkp = (struct pkcb *) malloc (size, M_PCB, M_WAITOK);
132 MALLOC(pkp
, struct pkcb
*, size
, M_PCB
, M_WAITOK
);
134 return ((struct pkcb
*)0);
135 bzero ((caddr_t
) pkp
, size
);
136 pkp
-> pk_lloutput
= pp
-> pr_output
;
137 pkp
-> pk_llctlinput
= (caddr_t (*)()) pp
-> pr_ctlinput
;
140 pkp
-> pk_state
= DTE_WAITING
;
141 pkp
-> pk_llnext
= llnext
;
142 insque (pkp
, &pkcb_q
);
148 if (xcp
-> xc_pwsize
== 0)
149 xcp
-> xc_pwsize
= DEFAULT_WINDOW_SIZE
;
150 if (xcp
-> xc_psize
== 0)
151 xcp
-> xc_psize
= X25_PS128
;
153 * Allocate logical channel descriptor vector
156 (void) pk_resize (pkp
);
162 register struct pkcb
*pkp
;
165 register struct protosw
*pp
;
168 * Essentially we have the choice to
169 * (a) go ahead and let the route be deleted and
170 * leave the pkcb associated with that route
171 * as it is, i.e. the connections stay open
172 * (b) do a pk_disconnect() on all channels associated
173 * with the route via the pkcb and then proceed.
175 * For the time being we stick with (b)
178 for (i
= 1; i
< pkp
-> pk_maxlcn
; ++i
)
179 if (pkp
-> pk_chan
[i
])
180 pk_disconnect (pkp
-> pk_chan
[i
]);
187 * First find the protoswitch to get hold of the link level
188 * protocol to be notified that the packet level entity is
191 pp
= pffindproto (AF_CCITT
, (int) pkp
-> pk_xcp
-> xc_lproto
, 0);
192 if (pp
== 0 || pp
-> pr_output
== 0) {
193 pk_message (0, pkp
-> pk_xcp
, "link level protosw error");
194 return (EPROTONOSUPPORT
);
197 pkp
-> pk_refcount
--;
198 if (!pkp
-> pk_refcount
) {
199 struct dll_ctlinfo ctlinfo
;
202 if (pkp
-> pk_rt
-> rt_llinfo
== (caddr_t
) pkp
)
203 pkp
-> pk_rt
-> rt_llinfo
= (caddr_t
) NULL
;
206 * Tell the link level that the pkcb is dissolving
208 if (pp
-> pr_ctlinput
&& pkp
-> pk_llnext
) {
209 ctlinfo
.dlcti_pcb
= pkp
-> pk_llnext
;
210 ctlinfo
.dlcti_rt
= pkp
-> pk_rt
;
211 (pp
-> pr_ctlinput
)(PRC_DISCONNECT_REQUEST
,
212 pkp
-> pk_xcp
, &ctlinfo
);
214 FREE((caddr_t
) pkp
-> pk_chan
, M_IFADDR
);
215 FREE((caddr_t
) pkp
, M_PCB
);
223 register struct pkcb
*pkp
;
225 struct pklcd
*dev_lcp
= 0;
226 struct x25config
*xcp
= pkp
-> pk_xcp
;
227 if (pkp
-> pk_chan
&&
228 (pkp
-> pk_maxlcn
!= xcp
-> xc_maxlcn
)) {
229 pk_restart (pkp
, X25_RESTART_NETWORK_CONGESTION
);
230 dev_lcp
= pkp
-> pk_chan
[0];
231 FREE((caddr_t
) pkp
-> pk_chan
, M_IFADDR
);
234 if (pkp
-> pk_chan
== 0) {
236 pkp
-> pk_maxlcn
= xcp
-> xc_maxlcn
;
237 size
= (pkp
-> pk_maxlcn
+ 1) * sizeof (struct pklcd
*);
239 // (struct pklcd **) malloc (size, M_IFADDR, M_WAITOK);
240 MALLOC(pkp
->pk_chan
, struct pklcd
**, size
, M_IFADDR
, M_WAITOK
);
241 if (pkp
-> pk_chan
) {
242 bzero ((caddr_t
) pkp
-> pk_chan
, size
);
244 * Allocate a logical channel descriptor for lcn 0
247 (dev_lcp
= pk_attach ((struct socket
*)0)) == 0)
249 dev_lcp
-> lcd_state
= READY
;
250 dev_lcp
-> lcd_pkp
= pkp
;
251 pkp
-> pk_chan
[0] = dev_lcp
;
262 * This procedure is called by the link level whenever the link
263 * becomes operational, is reset, or when the link goes down.
267 pk_ctlinput (code
, src
, addr
)
269 struct sockaddr
*src
;
272 register struct pkcb
*pkp
= (struct pkcb
*) addr
;
276 if (pkp
-> pk_state
== DTE_WAITING
)
277 pk_restart (pkp
, X25_RESTART_NETWORK_CONGESTION
);
281 pk_restart (pkp
, -1); /* Clear all active circuits */
282 pkp
-> pk_state
= DTE_WAITING
;
286 pk_restart (pkp
, X25_RESTART_NETWORK_CONGESTION
);
289 case PRC_CONNECT_INDICATION
: {
290 struct rtentry
*llrt
;
292 if ((llrt
= rtalloc1(src
, 0)) == 0)
294 else llrt
-> rt_refcnt
--;
296 pkp
= (((struct npaidbentry
*) llrt
-> rt_llinfo
) -> np_rt
) ?
297 (struct pkcb
*)(((struct npaidbentry
*) llrt
-> rt_llinfo
) -> np_rt
-> rt_llinfo
) : (struct pkcb
*) 0;
298 if (pkp
== (struct pkcb
*) 0)
300 pkp
-> pk_llnext
= addr
;
302 return ((caddr_t
) pkp
);
304 case PRC_DISCONNECT_INDICATION
:
305 pk_restart (pkp
, -1) ; /* Clear all active circuits */
306 pkp
-> pk_state
= DTE_WAITING
;
307 pkp
-> pk_llnext
= (caddr_t
) 0;
311 struct ifqueue pkintrq
;
313 * This routine is called if there are semi-smart devices that do HDLC
314 * in hardware and want to queue the packet and call level 3 directly
318 register struct mbuf
*m
;
319 register struct ifaddr
*ifa
;
320 register struct ifnet
*ifp
;
325 IF_DEQUEUE (&pkintrq
, m
);
329 if (m
-> m_len
< PKHEADERLN
) {
330 printf ("pkintr: packet too short (len=%d)\n",
338 struct mbuf
*pk_bad_packet
;
339 struct mbuf_cache pk_input_cache
= {0 };
343 * This procedure is called by a link level procedure whenever
344 * an information frame is received. It decodes the packet and
345 * demultiplexes based on the logical channel number.
347 * We change the original conventions of the UBC code here --
348 * since there may be multiple pkcb's for a given interface
349 * of type 802.2 class 2, we retrieve which one it is from
350 * m_pkthdr.rcvif (which has been overwritten by lower layers);
351 * That field is then restored for the benefit of upper layers which
352 * may make use of it, such as CLNP.
356 #define RESTART_DTE_ORIGINATED(xp) (((xp) -> packet_cause == X25_RESTART_DTE_ORIGINATED) || \
357 ((xp) -> packet_cause >= X25_RESTART_DTE_ORIGINATED2))
360 register struct mbuf
*m
;
362 register struct x25_packet
*xp
;
363 register struct pklcd
*lcp
;
364 register struct socket
*so
= 0;
365 register struct pkcb
*pkp
;
366 int ptype
, lcn
, lcdstate
= LISTEN
;
368 if (pk_input_cache
.mbc_size
|| pk_input_cache
.mbc_oldsize
)
369 mbuf_cache (&pk_input_cache
, m
);
370 if ((m
-> m_flags
& M_PKTHDR
) == 0)
373 if ((pkp
= (struct pkcb
*) m
-> m_pkthdr
.rcvif
) == 0)
375 xp
= mtod (m
, struct x25_packet
*);
376 ptype
= pk_decode (xp
);
378 lcp
= pkp
-> pk_chan
[lcn
];
381 * If the DTE is in Restart state, then it will ignore data,
382 * interrupt, call setup and clearing, flow control and reset
385 if (lcn
< 0 || lcn
> pkp
-> pk_maxlcn
) {
386 pk_message (lcn
, pkp
-> pk_xcp
, "illegal lcn");
391 pk_trace (pkp
-> pk_xcp
, m
, "P-In");
393 if (pkp
-> pk_state
!= DTE_READY
&& ptype
!= RESTART
&& ptype
!= RESTART_CONF
) {
399 lcdstate
= lcp
-> lcd_state
;
401 if (ptype
== CLEAR
) { /* idle line probe (Datapac specific) */
402 /* send response on lcd 0's output queue */
403 lcp
= pkp
-> pk_chan
[0];
404 lcp
-> lcd_template
= pk_template (lcn
, X25_CLEAR_CONFIRM
);
410 ptype
= INVALID_PACKET
;
413 if (lcn
== 0 && ptype
!= RESTART
&& ptype
!= RESTART_CONF
) {
414 pk_message (0, pkp
-> pk_xcp
, "illegal ptype (%d, %s) on lcn 0",
415 ptype
, pk_name
[ptype
/ MAXSTATES
]);
417 m_freem (pk_bad_packet
);
422 m
-> m_pkthdr
.rcvif
= pkp
-> pk_ia
-> ia_ifp
;
424 switch (ptype
+ lcdstate
) {
426 * Incoming Call packet received.
429 pk_incoming_call (pkp
, m
);
433 * Call collision: Just throw this "incoming call" away since
434 * the DCE will ignore it anyway.
436 case CALL
+ SENT_CALL
:
437 pk_message ((int) lcn
, pkp
-> pk_xcp
,
438 "incoming call collision");
442 * Call confirmation packet received. This usually means our
443 * previous connect request is now complete.
445 case CALL_ACCEPTED
+ SENT_CALL
:
446 MCHTYPE(m
, MT_CONTROL
);
447 pk_call_accepted (lcp
, m
);
451 * This condition can only happen if the previous state was
452 * SENT_CALL. Just ignore the packet, eventually a clear
453 * confirmation should arrive.
455 case CALL_ACCEPTED
+ SENT_CLEAR
:
459 * Clear packet received. This requires a complete tear down
460 * of the virtual circuit. Free buffers and control blocks.
461 * and send a clear confirmation.
464 case CLEAR
+ RECEIVED_CALL
:
465 case CLEAR
+ SENT_CALL
:
466 case CLEAR
+ DATA_TRANSFER
:
467 lcp
-> lcd_state
= RECEIVED_CLEAR
;
468 lcp
-> lcd_template
= pk_template (lcp
-> lcd_lcn
, X25_CLEAR_CONFIRM
);
470 pk_clearcause (pkp
, xp
);
471 if (lcp
-> lcd_upper
) {
472 MCHTYPE(m
, MT_CONTROL
);
473 lcp
-> lcd_upper (lcp
, m
);
480 * Clear collision: Treat this clear packet as a confirmation.
482 case CLEAR
+ SENT_CLEAR
:
487 * Clear confirmation received. This usually means the virtual
488 * circuit is now completely removed.
490 case CLEAR_CONF
+ SENT_CLEAR
:
495 * A clear confirmation on an unassigned logical channel - just
496 * ignore it. Note: All other packets on an unassigned channel
497 * results in a clear.
499 case CLEAR_CONF
+ READY
:
500 case CLEAR_CONF
+ LISTEN
:
504 * Data packet received. Pass on to next level. Move the Q and M
505 * bits into the data portion for the next level.
507 case DATA
+ DATA_TRANSFER
:
508 if (lcp
-> lcd_reset_condition
) {
509 ptype
= DELETE_PACKET
;
514 * Process the P(S) flow control information in this Data packet.
515 * Check that the packets arrive in the correct sequence and that
516 * they are within the "lcd_input_window". Input window rotation is
517 * initiated by the receive interface.
520 if (PS(xp
) != ((lcp
-> lcd_rsn
+ 1) % MODULUS
) ||
521 PS(xp
) == ((lcp
-> lcd_input_window
+ lcp
-> lcd_windowsize
) % MODULUS
)) {
523 pk_procerror (RESET
, lcp
, "p(s) flow control error", 1);
526 lcp
-> lcd_rsn
= PS(xp
);
528 if (pk_ack (lcp
, PR(xp
)) != PACKET_OK
) {
532 m
-> m_data
+= PKHEADERLN
;
533 m
-> m_len
-= PKHEADERLN
;
534 m
-> m_pkthdr
.len
-= PKHEADERLN
;
537 if (lcp
-> lcd_flags
& X25_MBS_HOLD
) {
538 register struct mbuf
*n
= lcp
-> lcd_cps
;
543 n
-> m_pkthdr
.len
+= m
-> m_pkthdr
.len
;
549 if (lcp
-> lcd_cpsmax
&&
550 n
-> m_pkthdr
.len
> lcp
-> lcd_cpsmax
) {
551 pk_procerror (RESET
, lcp
,
552 "C.P.S. overflow", 128);
555 q_and_d_bits
= 0xc0 & *(octet
*) xp
;
556 xp
= (struct x25_packet
*)
557 (mtod (m
, octet
*) - PKHEADERLN
);
558 *(octet
*) xp
|= q_and_d_bits
;
562 pk_flowcontrol (lcp
, 0, 1);
569 if (lcp
-> lcd_flags
& X25_MQBIT
) {
570 octet t
= (X25GBITS(xp
-> bits
, q_bit
)) ? t
= 0x80 : 0;
576 m
-> m_pkthdr
.len
+= 1;
577 *mtod (m
, octet
*) = t
;
581 * Discard Q-BIT packets if the application
582 * doesn't want to be informed of M and Q bit status
584 if (X25GBITS(xp
-> bits
, q_bit
)
585 && (lcp
-> lcd_flags
& X25_MQBIT
) == 0) {
588 * NB. This is dangerous: sending a RR here can
589 * cause sequence number errors if a previous data
590 * packet has not yet been passed up to the application
591 * (RR's are normally generated via PRU_RCVD).
593 pk_flowcontrol (lcp
, 0, 1);
595 sbappendrecord (&so
-> so_rcv
, m
);
601 * Interrupt packet received.
603 case INTERRUPT
+ DATA_TRANSFER
:
604 if (lcp
-> lcd_reset_condition
)
606 lcp
-> lcd_intrdata
= xp
-> packet_data
;
607 lcp
-> lcd_template
= pk_template (lcp
-> lcd_lcn
, X25_INTERRUPT_CONFIRM
);
609 m
-> m_data
+= PKHEADERLN
;
610 m
-> m_len
-= PKHEADERLN
;
611 m
-> m_pkthdr
.len
-= PKHEADERLN
;
612 MCHTYPE(m
, MT_OOBDATA
);
614 if (so
-> so_options
& SO_OOBINLINE
)
615 sbinsertoob (&so
-> so_rcv
, m
);
623 * Interrupt confirmation packet received.
625 case INTERRUPT_CONF
+ DATA_TRANSFER
:
626 if (lcp
-> lcd_reset_condition
)
628 if (lcp
-> lcd_intrconf_pending
== TRUE
)
629 lcp
-> lcd_intrconf_pending
= FALSE
;
631 pk_procerror (RESET
, lcp
, "unexpected packet", 43);
635 * Receiver ready received. Rotate the output window and output
636 * any data packets waiting transmission.
638 case RR
+ DATA_TRANSFER
:
639 if (lcp
-> lcd_reset_condition
||
640 pk_ack (lcp
, PR(xp
)) != PACKET_OK
) {
641 ptype
= DELETE_PACKET
;
644 if (lcp
-> lcd_rnr_condition
== TRUE
)
645 lcp
-> lcd_rnr_condition
= FALSE
;
650 * Receiver Not Ready received. Packets up to the P(R) can be
651 * be sent. Condition is cleared with a RR.
653 case RNR
+ DATA_TRANSFER
:
654 if (lcp
-> lcd_reset_condition
||
655 pk_ack (lcp
, PR(xp
)) != PACKET_OK
) {
656 ptype
= DELETE_PACKET
;
659 lcp
-> lcd_rnr_condition
= TRUE
;
663 * Reset packet received. Set state to FLOW_OPEN. The Input and
664 * Output window edges ar set to zero. Both the send and receive
665 * numbers are reset. A confirmation is returned.
667 case RESET
+ DATA_TRANSFER
:
668 if (lcp
-> lcd_reset_condition
)
669 /* Reset collision. Just ignore packet. */
672 pk_resetcause (pkp
, xp
);
673 lcp
-> lcd_window_condition
= lcp
-> lcd_rnr_condition
=
674 lcp
-> lcd_intrconf_pending
= FALSE
;
675 lcp
-> lcd_output_window
= lcp
-> lcd_input_window
=
676 lcp
-> lcd_last_transmitted_pr
= 0;
678 lcp
-> lcd_rsn
= MODULUS
- 1;
680 lcp
-> lcd_template
= pk_template (lcp
-> lcd_lcn
, X25_RESET_CONFIRM
);
686 wakeup ((caddr_t
) & so
-> so_timeo
);
692 * Reset confirmation received.
694 case RESET_CONF
+ DATA_TRANSFER
:
695 if (lcp
-> lcd_reset_condition
) {
696 lcp
-> lcd_reset_condition
= FALSE
;
700 pk_procerror (RESET
, lcp
, "unexpected packet", 32);
703 case DATA
+ SENT_CLEAR
:
704 ptype
= DELETE_PACKET
;
705 case RR
+ SENT_CLEAR
:
706 case RNR
+ SENT_CLEAR
:
707 case INTERRUPT
+ SENT_CLEAR
:
708 case INTERRUPT_CONF
+ SENT_CLEAR
:
709 case RESET
+ SENT_CLEAR
:
710 case RESET_CONF
+ SENT_CLEAR
:
711 /* Just ignore p if we have sent a CLEAR already.
716 * Restart sets all the permanent virtual circuits to the "Data
717 * Transfer" stae and all the switched virtual circuits to the
720 case RESTART
+ READY
:
721 switch (pkp
-> pk_state
) {
722 case DTE_SENT_RESTART
:
725 * If case the restart cause is "DTE originated" we
726 * have a DTE-DTE situation and are trying to resolve
727 * who is going to play DTE/DCE [ISO 8208:4.2-4.5]
729 if (RESTART_DTE_ORIGINATED(xp
)) {
730 pk_restart (pkp
, X25_RESTART_DTE_ORIGINATED
);
731 pk_message (0, pkp
-> pk_xcp
,
732 "RESTART collision");
733 if ((pkp
-> pk_restartcolls
++) > MAXRESTARTCOLLISIONS
) {
734 pk_message (0, pkp
-> pk_xcp
,
735 "excessive RESTART collisions");
736 pkp
-> pk_restartcolls
= 0;
740 pkp
-> pk_state
= DTE_READY
;
741 pkp
-> pk_dxerole
|= DTE_PLAYDTE
;
742 pkp
-> pk_dxerole
&= ~DTE_PLAYDCE
;
743 pk_message (0, pkp
-> pk_xcp
,
744 "Packet level operational");
745 pk_message (0, pkp
-> pk_xcp
,
746 "Assuming DTE role");
747 if (pkp
-> pk_dxerole
& DTE_CONNECTPENDING
)
748 pk_callcomplete (pkp
);
752 pk_restart (pkp
, -1);
753 pk_restartcause (pkp
, xp
);
754 pkp
-> pk_chan
[0] -> lcd_template
= pk_template (0,
755 X25_RESTART_CONFIRM
);
756 pk_output (pkp
-> pk_chan
[0]);
757 pkp
-> pk_state
= DTE_READY
;
758 pkp
-> pk_dxerole
|= RESTART_DTE_ORIGINATED(xp
) ? DTE_PLAYDCE
:
760 if (pkp
-> pk_dxerole
& DTE_PLAYDTE
) {
761 pkp
-> pk_dxerole
&= ~DTE_PLAYDCE
;
762 pk_message (0, pkp
-> pk_xcp
,
763 "Assuming DTE role");
765 pkp
-> pk_dxerole
&= ~DTE_PLAYDTE
;
766 pk_message (0, pkp
-> pk_xcp
,
767 "Assuming DCE role");
769 if (pkp
-> pk_dxerole
& DTE_CONNECTPENDING
)
770 pk_callcomplete (pkp
);
775 * Restart confirmation received. All logical channels are set
778 case RESTART_CONF
+ READY
:
779 switch (pkp
-> pk_state
) {
780 case DTE_SENT_RESTART
:
781 pkp
-> pk_state
= DTE_READY
;
782 pkp
-> pk_dxerole
|= DTE_PLAYDTE
;
783 pkp
-> pk_dxerole
&= ~DTE_PLAYDCE
;
784 pk_message (0, pkp
-> pk_xcp
,
785 "Packet level operational");
786 pk_message (0, pkp
-> pk_xcp
,
787 "Assuming DTE role");
788 if (pkp
-> pk_dxerole
& DTE_CONNECTPENDING
)
789 pk_callcomplete (pkp
);
793 /* Restart local procedure error. */
794 pk_restart (pkp
, X25_RESTART_LOCAL_PROCEDURE_ERROR
);
795 pkp
-> pk_state
= DTE_SENT_RESTART
;
796 pkp
-> pk_dxerole
&= ~(DTE_PLAYDTE
| DTE_PLAYDCE
);
802 pk_procerror (CLEAR
, lcp
, "unknown packet error", 33);
803 pk_message (lcn
, pkp
-> pk_xcp
,
804 "\"%s\" unexpected in \"%s\" state",
805 pk_name
[ptype
/MAXSTATES
], pk_state
[lcdstate
]);
807 pk_message (lcn
, pkp
-> pk_xcp
,
808 "packet arrived on unassigned lcn");
811 if (so
== 0 && lcp
&& lcp
-> lcd_upper
&& lcdstate
== DATA_TRANSFER
) {
812 if (ptype
!= DATA
&& ptype
!= INTERRUPT
)
813 MCHTYPE(m
, MT_CONTROL
);
814 lcp
-> lcd_upper (lcp
, m
);
815 } else if (ptype
!= DATA
&& ptype
!= INTERRUPT
)
820 prune_dnic (from
, to
, dnicname
, xcp
)
821 char *from
, *to
, *dnicname
;
822 register struct x25config
*xcp
;
824 register char *cp1
= from
, *cp2
= from
;
825 if (xcp
-> xc_prepnd0
&& *cp1
== '0') {
829 if (xcp
-> xc_nodnic
) {
830 for (cp1
= dnicname
; *cp2
= *cp1
++;)
835 for (cp1
= dnicname
; *cp2
= *cp1
++;)
839 pk_simple_bsd (from
, to
, lower
, len
)
840 register octet
*from
, *to
;
850 c
&= 0x0f; c
|= 0x30; *to
++ = c
; lower
++;
856 pk_from_bcd (a
, iscalling
, sa
, xcp
)
857 register struct x25_calladdr
*a
;
859 register struct sockaddr_x25
*sa
;
860 register struct x25config
*xcp
;
862 octet buf
[MAXADDRLN
+1];
866 bzero ((caddr_t
) sa
, sizeof (*sa
));
867 sa
-> x25_len
= sizeof (*sa
);
868 sa
-> x25_family
= AF_CCITT
;
870 cp
= a
-> address_field
+ (X25GBITS(a
-> addrlens
, called_addrlen
) / 2);
871 count
= X25GBITS(a
-> addrlens
, calling_addrlen
);
872 pk_simple_bsd (cp
, buf
, X25GBITS(a
-> addrlens
, called_addrlen
), count
);
874 count
= X25GBITS(a
-> addrlens
, called_addrlen
);
875 pk_simple_bsd (a
-> address_field
, buf
, 0, count
);
877 if (xcp
-> xc_addr
.x25_net
&& (xcp
-> xc_nodnic
|| xcp
-> xc_prepnd0
)) {
878 octet dnicname
[sizeof (long) * NBBY
/3 + 2];
880 sprintf ((char *) dnicname
, "%d", xcp
-> xc_addr
.x25_net
);
881 prune_dnic ((char *) buf
, sa
-> x25_addr
, dnicname
, xcp
);
883 bcopy ((caddr_t
) buf
, (caddr_t
) sa
-> x25_addr
, count
+ 1);
887 save_extra (m0
, fp
, so
)
892 register struct mbuf
*m
;
893 struct cmsghdr cmsghdr
;
894 if (m
= m_copy (m
, 0, (int)M_COPYALL
)) {
895 int off
= fp
- mtod (m0
, octet
*);
896 int len
= m
-> m_pkthdr
.len
- off
+ sizeof (cmsghdr
);
897 cmsghdr
.cmsg_len
= len
;
898 cmsghdr
.cmsg_level
= AF_CCITT
;
899 cmsghdr
.cmsg_type
= PK_FACILITIES
;
901 M_PREPEND (m
, sizeof (cmsghdr
), M_DONTWAIT
);
904 bcopy ((caddr_t
)&cmsghdr
, mtod (m
, caddr_t
), sizeof (cmsghdr
));
905 MCHTYPE(m
, MT_CONTROL
);
906 sbappendrecord (&so
-> so_rcv
, m
);
911 * This routine handles incoming call packets. It matches the protocol
912 * field on the Call User Data field (usually the first four bytes) with
913 * sockets awaiting connections.
916 pk_incoming_call (pkp
, m0
)
920 register struct pklcd
*lcp
= 0, *l
;
921 register struct sockaddr_x25
*sa
;
922 register struct x25_calladdr
*a
;
923 register struct socket
*so
= 0;
924 struct x25_packet
*xp
= mtod (m0
, struct x25_packet
*);
926 struct x25config
*xcp
= pkp
-> pk_xcp
;
927 int len
= m0
-> m_pkthdr
.len
;
929 char *errstr
= "server unavailable";
933 /* First, copy the data from the incoming call packet to a X25 address
934 descriptor. It is to be regretted that you have
935 to parse the facilities into a sockaddr to determine
936 if reverse charging is being requested */
937 if ((m
= m_get (M_DONTWAIT
, MT_SONAME
)) == 0)
939 sa
= mtod (m
, struct sockaddr_x25
*);
940 a
= (struct x25_calladdr
*) &xp
-> packet_data
;
941 facp
= u
= (octet
*) (a
-> address_field
+
942 ((X25GBITS(a
-> addrlens
, called_addrlen
) + X25GBITS(a
-> addrlens
, calling_addrlen
) + 1) / 2));
944 udlen
= min (16, ((octet
*) xp
) + len
- u
);
947 pk_from_bcd (a
, 1, sa
, pkp
-> pk_xcp
); /* get calling address */
948 pk_parse_facilities (facp
, sa
);
949 bcopy ((caddr_t
) u
, sa
-> x25_udata
, udlen
);
950 sa
-> x25_udlen
= udlen
;
953 * Now, loop through the listen sockets looking for a match on the
954 * PID. That is the first few octets of the user data field.
955 * This is the closest thing to a port number for X.25 packets.
956 * It does provide a way of multiplexing services at the user level.
959 for (l
= pk_listenhead
; l
; l
= l
-> lcd_listen
) {
960 struct sockaddr_x25
*sxp
= l
-> lcd_ceaddr
;
962 if (bcmp (sxp
-> x25_udata
, u
, sxp
-> x25_udlen
))
964 if (sxp
-> x25_net
&&
965 sxp
-> x25_net
!= xcp
-> xc_addr
.x25_net
)
968 * don't accept incoming calls with the D-Bit on
969 * unless the server agrees
971 if (X25GBITS(xp
-> bits
, d_bit
) && !(sxp
-> x25_opts
.op_flags
& X25_DBIT
)) {
972 errstr
= "incoming D-Bit mismatch";
976 * don't accept incoming collect calls unless
977 * the server sets the reverse charging option.
979 if ((sxp
-> x25_opts
.op_flags
& (X25_OLDSOCKADDR
|X25_REVERSE_CHARGE
)) == 0 &&
980 sa
-> x25_opts
.op_flags
& X25_REVERSE_CHARGE
) {
981 errstr
= "incoming collect call refused";
985 if (so
= sonewconn (l
-> lcd_so
, SS_ISCONNECTED
))
986 lcp
= (struct pklcd
*) so
-> so_pcb
;
988 lcp
= pk_attach ((struct socket
*) 0);
991 * Insufficient space or too many unaccepted
992 * connections. Just throw the call away.
994 errstr
= "server malfunction";
997 lcp
-> lcd_upper
= l
-> lcd_upper
;
998 lcp
-> lcd_upnext
= l
-> lcd_upnext
;
999 lcp
-> lcd_lcn
= lcn
;
1000 lcp
-> lcd_state
= RECEIVED_CALL
;
1001 sa
-> x25_opts
.op_flags
|= (sxp
-> x25_opts
.op_flags
&
1002 ~X25_REVERSE_CHARGE
) | l
-> lcd_flags
;
1003 pk_assoc (pkp
, lcp
, sa
);
1004 lcp
-> lcd_faddr
= *sa
;
1005 lcp
-> lcd_laddr
.x25_udlen
= sxp
-> x25_udlen
;
1006 lcp
-> lcd_craddr
= &lcp
-> lcd_faddr
;
1007 lcp
-> lcd_template
= pk_template (lcp
-> lcd_lcn
, X25_CALL_ACCEPTED
);
1008 if (lcp
-> lcd_flags
& X25_DBIT
) {
1009 if (X25GBITS(xp
-> bits
, d_bit
))
1010 X25SBITS(mtod (lcp
-> lcd_template
,
1011 struct x25_packet
*) -> bits
, d_bit
, 1);
1013 lcp
-> lcd_flags
&= ~X25_DBIT
;
1018 if (so
-> so_options
& SO_OOBINLINE
)
1019 save_extra (m0
, facp
, so
);
1020 } else if (lcp
-> lcd_upper
) {
1021 (*lcp
-> lcd_upper
) (lcp
, m0
);
1028 * If the call fails for whatever reason, we still need to build a
1029 * skeleton LCD in order to be able to properly receive the CLEAR
1032 #ifdef WATERLOO /* be explicit */
1033 if (l
== 0 && bcmp (sa
-> x25_udata
, "ean", 3) == 0)
1034 pk_message (lcn
, pkp
-> pk_xcp
, "host=%s ean%c: %s",
1035 sa
-> x25_addr
, sa
-> x25_udata
[3] & 0xff, errstr
);
1036 else if (l
== 0 && bcmp (sa
-> x25_udata
, "\1\0\0\0", 4) == 0)
1037 pk_message (lcn
, pkp
-> pk_xcp
, "host=%s x29d: %s",
1038 sa
-> x25_addr
, errstr
);
1041 pk_message (lcn
, pkp
-> pk_xcp
, "host=%s pid=%x %x %x %x: %s",
1042 sa
-> x25_addr
, sa
-> x25_udata
[0] & 0xff,
1043 sa
-> x25_udata
[1] & 0xff, sa
-> x25_udata
[2] & 0xff,
1044 sa
-> x25_udata
[3] & 0xff, errstr
);
1045 if ((lcp
= pk_attach ((struct socket
*)0)) == 0) {
1049 lcp
-> lcd_lcn
= lcn
;
1050 lcp
-> lcd_state
= RECEIVED_CALL
;
1051 pk_assoc (pkp
, lcp
, sa
);
1053 pk_clear (lcp
, 0, 1);
1056 pk_call_accepted (lcp
, m
)
1060 register struct x25_calladdr
*ap
;
1061 register octet
*fcp
;
1062 struct x25_packet
*xp
= mtod (m
, struct x25_packet
*);
1063 int len
= m
-> m_len
;
1065 lcp
-> lcd_state
= DATA_TRANSFER
;
1067 soisconnected (lcp
-> lcd_so
);
1068 if ((lcp
-> lcd_flags
& X25_DBIT
) && (X25GBITS(xp
-> bits
, d_bit
) == 0))
1069 lcp
-> lcd_flags
&= ~X25_DBIT
;
1071 ap
= (struct x25_calladdr
*) &xp
-> packet_data
;
1072 fcp
= (octet
*) ap
-> address_field
+ (X25GBITS(ap
-> addrlens
, calling_addrlen
) +
1073 X25GBITS(ap
-> addrlens
, called_addrlen
) + 1) / 2;
1074 if (fcp
+ *fcp
<= ((octet
*) xp
) + len
)
1075 pk_parse_facilities (fcp
, lcp
-> lcd_ceaddr
);
1077 pk_assoc (lcp
-> lcd_pkp
, lcp
, lcp
-> lcd_ceaddr
);
1078 if (lcp
-> lcd_so
== 0 && lcp
-> lcd_upper
)
1079 lcp
-> lcd_upper (lcp
, m
);
1082 pk_parse_facilities (fcp
, sa
)
1083 register octet
*fcp
;
1084 register struct sockaddr_x25
*sa
;
1086 register octet
*maxfcp
;
1088 maxfcp
= fcp
+ *fcp
;
1090 while (fcp
< maxfcp
) {
1092 * Ignore national DCE or DTE facilities
1094 if (*fcp
== 0 || *fcp
== 0xff)
1097 case FACILITIES_WINDOWSIZE
:
1098 sa
-> x25_opts
.op_wsize
= fcp
[1];
1102 case FACILITIES_PACKETSIZE
:
1103 sa
-> x25_opts
.op_psize
= fcp
[1];
1107 case FACILITIES_THROUGHPUT
:
1108 sa
-> x25_opts
.op_speed
= fcp
[1];
1112 case FACILITIES_REVERSE_CHARGE
:
1114 sa
-> x25_opts
.op_flags
|= X25_REVERSE_CHARGE
;
1116 * Datapac specific: for a X.25(1976) DTE, bit 2
1117 * indicates a "hi priority" (eg. international) call.
1119 if (fcp
[1] & 02 && sa
-> x25_opts
.op_psize
== 0)
1120 sa
-> x25_opts
.op_psize
= X25_PS128
;
1125 /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/
1126 switch ((*fcp
& 0xc0) >> 6) {
1127 case 0: /* class A */