]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netiso/if_cons.c
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) 1991, 1993
24 * The Regents of the University of California. All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. All advertising materials mentioning features or use of this software
35 * must display the following acknowledgement:
36 * This product includes software developed by the University of
37 * California, Berkeley and its contributors.
38 * 4. Neither the name of the University nor the names of its contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
42 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * @(#)if_cons.c 8.1 (Berkeley) 6/10/93
57 /***********************************************************
58 Copyright IBM Corporation 1987
62 Permission to use, copy, modify, and distribute this software and its
63 documentation for any purpose and without fee is hereby granted,
64 provided that the above copyright notice appear in all copies and that
65 both that copyright notice and this permission notice appear in
66 supporting documentation, and that the name of IBM not be
67 used in advertising or publicity pertaining to distribution of the
68 software without specific, written prior permission.
70 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
71 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
72 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
73 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
74 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
75 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
78 ******************************************************************/
81 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
84 * cons.c - Connection Oriented Network Service:
85 * including support for a) user transport-level service,
86 * b) COSNS below CLNP, and c) CONS below TP.
93 unsigned LAST_CALL_PCB
;
94 #else /* ARGO_DEBUG */
96 #endif /* ARGO_DEBUG */
99 #include <sys/param.h>
100 #include <sys/systm.h>
101 #include <sys/mbuf.h>
102 #include <sys/protosw.h>
103 #include <sys/socket.h>
104 #include <sys/socketvar.h>
105 #include <sys/errno.h>
106 #include <sys/ioctl.h>
107 #include <sys/tsleep.h>
110 #include <net/netisr.h>
111 #include <net/route.h>
113 #include <netiso/iso_errno.h>
114 #include <netiso/argo_debug.h>
115 #include <netiso/tp_trace.h>
116 #include <netiso/iso.h>
117 #include <netiso/cons.h>
118 #include <netiso/iso_pcb.h>
120 #include <netccitt/x25.h>
121 #include <netccitt/pk.h>
122 #include <netccitt/pk_var.h>
126 #define MT_XCONN 0x50
127 #define MT_XCLOSE 0x51
128 #define MT_XCONFIRM 0x52
129 #define MT_XDATA 0x53
130 #define MT_XHEADER 0x54
132 #define MT_XCONN MT_DATA
133 #define MT_XCLOSE MT_DATA
134 #define MT_XCONFIRM MT_DATA
135 #define MT_XDATA MT_DATA
136 #define MT_XHEADER MT_HEADER
137 #endif /* ARGO_DEBUG */
141 /*********************************************************************
142 * cons.c - CONS interface to the x.25 layer
144 * TODO: figure out what resources we might run out of besides mbufs.
145 * If we run out of any of them (including mbufs) close and recycle
146 * lru x% of the connections, for some parameter x.
148 * There are 2 interfaces from above:
150 * cons CO network service
151 * TP associates a transport connection with a network connection.
152 * cons_output( isop, m, len, isdgm==0 )
155 * It's a datagram service, like clnp is. - even though it calls
156 * cons_output( isop, m, len, isdgm==1 )
157 * it eventually goes through
158 * cosns_output(ifp, m, dst).
159 * TP4 permits multiplexing (reuse, possibly simultaneously) of the
160 * network connections.
161 * This means that many sockets (many tpcbs) may be associated with
162 * this pklcd, hence cannot have a back ptr from pklcd to a tpcb.
163 * co_flags & CONSF_DGM
164 * co_socket is null since there may be many sockets that use this pklcd.
167 streams would really be nice. sigh.
169 PVCs could be handled by config-ing a cons with an address and with the
170 IFF_POINTTOPOINT flag on. This code would then have to skip the
171 connection setup stuff for pt-to-pt links.
174 *********************************************************************/
177 #define CONS_IFQMAXLEN 5
180 /* protosw pointers for getting to higher layer */
181 Static
struct protosw
*CLNP_proto
;
182 Static
struct protosw
*TP_proto
;
183 Static
struct protosw
*X25_proto
;
184 Static
int issue_clear_req();
187 extern struct ifaddr
*ifa_ifwithnet();
188 #endif /* PHASEONE */
190 extern struct ifaddr
*ifa_ifwithaddr();
192 extern struct isopcb tp_isopcb
; /* chain of all TP pcbs */
195 Static
int parse_facil(), NSAPtoDTE(), make_partial_x25_packet();
196 Static
int FACILtoNSAP(), DTEtoNSAP();
197 Static
struct pklcd
*cons_chan_to_pcb();
199 #define HIGH_NIBBLE 1
203 * NAME: nibble_copy()
204 * FUNCTION and ARGUMENTS:
205 * copies (len) nibbles from (src_octet), high or low nibble
206 * to (dst_octet), high or low nibble,
207 * src_nibble & dst_nibble should be:
208 * HIGH_NIBBLE (1) if leftmost 4 bits/ most significant nibble
209 * LOW_NIBBLE (0) if rightmost 4 bits/ least significant nibble
213 nibble_copy(src_octet
, src_nibble
, dst_octet
, dst_nibble
, len
)
214 register char *src_octet
;
215 register char *dst_octet
;
216 register unsigned src_nibble
;
217 register unsigned dst_nibble
;
222 register unsigned dshift
, sshift
;
225 printf("nibble_copy ( 0x%x, 0x%x, 0x%x, 0x%x 0x%x)\n",
226 src_octet
, src_nibble
, dst_octet
, dst_nibble
, len
);
230 dshift
= dst_nibble
<< 2;
231 sshift
= src_nibble
<< 2;
233 for (i
=0; i
<len
; i
++) {
234 /* clear dst_nibble */
235 *dst_octet
&= ~(0xf<< dshift
);
238 *dst_octet
|= ( 0xf & (*src_octet
>> sshift
))<< dshift
;
242 src_nibble
= 1-src_nibble
;
243 dst_nibble
= 1-dst_nibble
;
244 src_octet
+= src_nibble
;
245 dst_octet
+= dst_nibble
;
248 printf("nibble_copy DONE\n");
253 * NAME: nibble_match()
254 * FUNCTION and ARGUMENTS:
255 * compares src_octet/src_nibble and dst_octet/dst_nibble for len nibbles.
256 * RETURNS: 0 if they differ, 1 if they are the same.
259 nibble_match( src_octet
, src_nibble
, dst_octet
, dst_nibble
, len
)
260 register char *src_octet
;
261 register char *dst_octet
;
262 register unsigned src_nibble
;
263 register unsigned dst_nibble
;
268 register unsigned dshift
, sshift
;
269 u_char nibble_a
, nibble_b
;
272 printf("nibble_match ( 0x%x, 0x%x, 0x%x, 0x%x 0x%x)\n",
273 src_octet
, src_nibble
, dst_octet
, dst_nibble
, len
);
277 dshift
= dst_nibble
<< 2;
278 sshift
= src_nibble
<< 2;
280 for (i
=0; i
<len
; i
++) {
281 nibble_b
= ((*dst_octet
)>>dshift
) & 0xf;
282 nibble_a
= ( 0xf & (*src_octet
>> sshift
));
283 if (nibble_b
!= nibble_a
)
288 src_nibble
= 1-src_nibble
;
289 dst_nibble
= 1-dst_nibble
;
290 src_octet
+= src_nibble
;
291 dst_octet
+= dst_nibble
;
294 printf("nibble_match DONE\n");
300 **************************** NET PROTOCOL cons ***************************
307 * initialize the protocol
311 int tp_incoming(), clnp_incoming();
314 CLNP_proto
= pffindproto(AF_ISO
, ISOPROTO_CLNP
, SOCK_DGRAM
);
315 X25_proto
= pffindproto(AF_ISO
, ISOPROTO_X25
, SOCK_STREAM
);
316 TP_proto
= pffindproto(AF_ISO
, ISOPROTO_TP0
, SOCK_SEQPACKET
);
318 printf("cons_init end : cnlp_proto 0x%x cons proto 0x%x tp proto 0x%x\n",
319 CLNP_proto
, X25_proto
, TP_proto
);
322 pk_protolisten(0x81, 0, clnp_incoming
);
323 pk_protolisten(0x82, 0, esis_incoming
);
324 pk_protolisten(0x84, 0, tp8878_A_incoming
);
325 pk_protolisten(0, 0, tp_incoming
);
331 register struct mbuf
*m
;
333 register struct isopcb
*isop
;
336 if (iso_pcballoc((struct socket
*)0, &tp_isopcb
)) {
340 isop
= tp_isopcb
.isop_next
;
341 lcp
->lcd_upper
= cons_tpinput
;
342 lcp
->lcd_upnext
= (caddr_t
)isop
;
343 lcp
->lcd_send(lcp
); /* Confirms call */
344 isop
->isop_chan
= (caddr_t
)lcp
;
345 isop
->isop_laddr
= &isop
->isop_sladdr
;
346 isop
->isop_faddr
= &isop
->isop_sfaddr
;
347 DTEtoNSAP(isop
->isop_laddr
, &lcp
->lcd_laddr
);
348 DTEtoNSAP(isop
->isop_faddr
, &lcp
->lcd_faddr
);
349 parse_facil(lcp
, isop
, &(mtod(m
, struct x25_packet
*)->packet_data
),
350 m
->m_pkthdr
.len
- PKHEADERLN
);
353 cons_tpinput(lcp
, m0
)
357 register struct isopcb
*isop
= (struct isopcb
*)lcp
->lcd_upnext
;
358 register struct x25_packet
*xp
;
359 int cmd
, ptype
= CLEAR
;
368 tpcons_input(m0
, isop
->isop_faddr
, isop
->isop_laddr
, (caddr_t
)lcp
);
372 switch (ptype
= pk_decode(mtod(m0
, struct x25_packet
*))) {
375 cmd
= PRC_CONS_SEND_DONE
;
379 if (lcp
->lcd_sb
.sb_mb
)
380 lcp
->lcd_send(lcp
); /* XXX - fix this */
394 tpcons_ctlinput(cmd
, isop
->isop_faddr
, isop
);
395 if (cmd
= PRC_ROUTEDEAD
&& isop
->isop_refcnt
== 0)
401 * NAME: cons_connect()
403 * tpcons_pcbconnect() when opening a new connection.
404 * FUNCTION anD ARGUMENTS:
405 * Figures out which device to use, finding a route if one doesn't
411 register struct isopcb
*isop
;
413 register struct pklcd
*lcp
= (struct pklcd
*)isop
->isop_chan
;
414 register struct mbuf
*m
;
419 printf("cons_connect(0x%x): ", isop
);
420 dump_isoaddr(isop
->isop_faddr
);
422 dump_isoaddr(isop
->isop_laddr
);
425 NSAPtoDTE(isop
->isop_faddr
, &lcp
->lcd_faddr
);
426 lcp
->lcd_upper
= cons_tpinput
;
427 lcp
->lcd_upnext
= (caddr_t
)isop
;
430 "calling make_partial_x25_packet( 0x%x, 0x%x, 0x%x)\n",
431 &lcp
->lcd_faddr
, &lcp
->lcd_laddr
,
432 isop
->isop_socket
->so_proto
->pr_protocol
);
434 if ((error
= make_partial_x25_packet(isop
, lcp
, m
)) == 0)
435 error
= pk_connect(lcp
, &lcp
->lcd_faddr
);
440 **************************** DEVICE cons ***************************
445 * NAME: cons_ctlinput()
447 * lower layer when ECN_CLEAR occurs : this routine is here
448 * for consistency - cons subnet service calls its higher layer
449 * through the protosw entry.
450 * FUNCTION & ARGUMENTS:
451 * cmd is a PRC_* command, list found in ../sys/protosw.h
452 * copcb is the obvious.
453 * This serves the higher-layer cons service.
454 * NOTE: this takes 3rd arg. because cons uses it to inform itself
455 * of things (timeouts, etc) but has a pcb instead of an address.
457 cons_ctlinput(cmd
, sa
, copcb
)
460 register struct pklcd
*copcb
;
465 find_error_reason( xp
)
466 register struct x25_packet
*xp
;
468 extern u_char x25_error_stats
[];
472 cause
= 4[(char *)xp
];
476 /* DTE originated; look at the diagnostic */
477 error
= (CONL_ERROR_MASK
| cause
);
480 case 0x01: /* number busy */
482 case 0x09: /* Out of order */
484 case 0x11: /* Remot Procedure Error */
486 case 0x19: /* reverse charging accept not subscribed */
488 case 0x21: /* Incampat destination */
490 case 0x29: /* fast select accept not subscribed */
492 case 0x39: /* ship absent */
494 case 0x03: /* invalid facil request */
496 case 0x0b: /* access barred */
498 case 0x13: /* local procedure error */
500 case 0x05: /* network congestion */
502 case 0x8d: /* not obtainable */
504 case 0x95: /* RPOA out of order */
507 * so we don't have to have so many perror entries
509 error
= (CONL_ERROR_MASK
| 0x100 | (cause
& ~0x80));
512 case 0xc1: /* gateway-detected proc error */
513 case 0xc3: /* gateway congestion */
515 error
= (CONL_ERROR_MASK
| 0x100 | cause
);
519 /* otherwise, a *hopefully* valid perror exists in the e_reason field */
520 error
= xp
->packet_data
;
522 printf("Incoming PKT TYPE 0x%x with reason 0x%x\n",
525 error
= E_CO_HLI_DISCA
;
537 * NAME: make_partial_x25_packet()
539 * FUNCTION and ARGUMENTS:
540 * Makes part of an X.25 call packet, for use by x25.
541 * (src) and (dst) are the NSAP-addresses of source and destination.
542 * (buf) is a ptr to a buffer into which to write this partial header.
544 * 0 Facility length (in octets)
545 * 1 Facility field, which is a set of:
547 * m+1 facil param len (for >2-byte facilities) in octets
548 * m+2..p facil param field
549 * q user data (protocol identification octet)
557 * Stores facilites mbuf in X.25 control block, where the connect
558 * routine knows where to look for it.
562 int cons_use_facils
= 1;
564 int cons_use_facils
= 0;
565 #endif /* X25_1984 */
567 int cons_use_udata
= 1; /* KLUDGE FOR DEBUGGING */
570 make_partial_x25_packet(isop
, lcp
)
577 register caddr_t ptr
;
578 register int len
= 0;
586 printf("make_partial_x25_packet(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
587 isop
->isop_laddr
, isop
->isop_faddr
, proto
, m
, flag
);
589 if (cons_use_udata
) {
590 if (isop
->isop_x25crud_len
> 0) {
592 * The user specified something. Stick it in
594 bcopy(isop
->isop_x25crud
, lcp
->lcd_faddr
.x25_udata
,
595 isop
->isop_x25crud_len
);
596 lcp
->lcd_faddr
.x25_udlen
= isop
->isop_x25crud_len
;
600 if (cons_use_facils
== 0) {
601 lcp
->lcd_facilities
= 0;
604 MGETHDR(m
, MT_DATA
, M_WAITOK
);
607 buf
= mtod(m
, caddr_t
);
610 /* ptr now points to facil length (len of whole facil field in OCTETS */
613 pk_build_facilities(m
, &lcp
->lcd_faddr
, 0);
616 printf("make_partial calling: ptr 0x%x, len 0x%x\n", ptr
,
617 isop
->isop_laddr
->siso_addr
.isoa_len
);
619 if (cons_use_facils
) {
620 *ptr
++ = 0; /* Marker to separate X.25 facitilies from CCITT ones */
622 *ptr
= 0xcb; /* calling facility code */
624 ptr
++; /* leave room for facil param len (in OCTETS + 1) */
625 ptr
++; /* leave room for the facil param len (in nibbles),
626 * high two bits of which indicate full/partial NSAP
628 len
= isop
->isop_laddr
->siso_addr
.isoa_len
;
629 bcopy( isop
->isop_laddr
->siso_data
, ptr
, len
);
630 *(ptr
-2) = len
+1; /* facil param len in octets */
631 *(ptr
-1) = len
<<1; /* facil param len in nibbles */
635 printf("make_partial called: ptr 0x%x, len 0x%x\n", ptr
,
636 isop
->isop_faddr
->siso_addr
.isoa_len
);
638 *ptr
= 0xc9; /* called facility code */
640 ptr
++; /* leave room for facil param len (in OCTETS + 1) */
641 ptr
++; /* leave room for the facil param len (in nibbles),
642 * high two bits of which indicate full/partial NSAP
644 len
= isop
->isop_faddr
->siso_nlen
;
645 bcopy(isop
->isop_faddr
->siso_data
, ptr
, len
);
646 *(ptr
-2) = len
+1; /* facil param len = addr len + 1 for each of these
647 * two length fields, in octets */
648 *(ptr
-1) = len
<<1; /* facil param len in nibbles */
652 *facil_len
= ptr
- facil_len
- 1;
653 if (*facil_len
> MAX_FACILITIES
)
654 return E_CO_PNA_LONG
;
656 buflen
= (int)(ptr
- buf
);
661 printf("ECN_CONNECT DATA buf 0x%x len %d (0x%x)\n",
662 buf
, buflen
, buflen
);
663 for( i
=0; i
< buflen
; ) {
664 printf("+%d: %x %x %x %x %x %x %x %x\n",
666 *(buf
+i
), *(buf
+i
+1), *(buf
+i
+2), *(buf
+i
+3),
667 *(buf
+i
+4), *(buf
+i
+5), *(buf
+i
+6), *(buf
+i
+7));
672 printf("make_partial returns buf 0x%x size 0x%x bytes\n",
673 mtod(m
, caddr_t
), buflen
);
677 return E_CO_PNA_LONG
;
679 m
->m_pkthdr
.len
= m
->m_len
= buflen
;
680 lcp
->lcd_facilities
= m
;
687 * make_partial_x25_packet()
688 * FUNCTION and ARGUMENTS:
689 * get a DTE address from an NSAP-address (struct sockaddr_iso)
690 * (dst_octet) is the octet into which to begin stashing the DTE addr
691 * (dst_nibble) takes 0 or 1. 1 means begin filling in the DTE addr
692 * in the high-order nibble of dst_octet. 0 means low-order nibble.
693 * (addr) is the NSAP-address
694 * (flag) is true if the transport suffix is to become the
695 * last two digits of the DTE address
696 * A DTE address is a series of ASCII digits
698 * A DTE address may have leading zeros. The are significant.
699 * 1 digit per nibble, may be an odd number of nibbles.
701 * An NSAP-address has the DTE address in the IDI. Leading zeros are
702 * significant. Trailing hex f indicates the end of the DTE address.
703 * The IDI is a series of BCD digits, one per nibble.
706 * # significant digits in the DTE address, -1 if error.
710 NSAPtoDTE(siso
, sx25
)
711 register struct sockaddr_iso
*siso
;
712 register struct sockaddr_x25
*sx25
;
717 printf("NSAPtoDTE: nsap: %s\n", clnp_iso_addrp(&siso
->siso_addr
));
720 if (siso
->siso_data
[0] == AFI_37
) {
721 register char *out
= sx25
->x25_addr
;
722 register char *in
= siso
->siso_data
+ 1;
724 char *lim
= siso
->siso_data
+ siso
->siso_nlen
;
729 nibble
= ((lowNibble
? *in
++ : (*in
>> 4)) & 0xf) | 0x30;
731 if (nibble
!= 0x3f && out
< olim
)
734 dtelen
= out
- sx25
->x25_addr
;
737 /* error = iso_8208snparesolve(addr, x121string, &x121strlen);*/
738 register struct rtentry
*rt
;
739 extern struct sockaddr_iso blank_siso
;
740 struct sockaddr_iso nsiso
;
743 bcopy(nsiso
.siso_data
, siso
->siso_data
,
744 nsiso
.siso_nlen
= siso
->siso_nlen
);
745 if (rt
= rtalloc1(&nsiso
, 1)) {
746 register struct sockaddr_x25
*sxx
=
747 (struct sockaddr_x25
*)rt
->rt_gateway
;
748 register char *in
= sxx
->x25_addr
;
751 if (sxx
&& sxx
->x25_family
== AF_CCITT
) {
752 bcopy(sx25
->x25_addr
, sxx
->x25_addr
, sizeof(sx25
->x25_addr
));
754 dtelen
= in
- sxx
->x25_addr
;
762 * NAME: FACILtoNSAP()
765 * FUNCTION and ARGUMENTS:
766 * Creates and NSAP in the sockaddr_iso (addr) from the
767 * x.25 facility found at buf - 1.
769 * 0 if ok, -1 if error.
773 FACILtoNSAP(addr
, buf
)
774 register u_char
*buf
;
775 register struct sockaddr_iso
*addr
;
777 int len_in_nibbles
= *++buf
& 0x3f;
778 u_char buf_len
= (len_in_nibbles
+ 1) >> 1;; /* in bytes */
781 printf("FACILtoNSAP( 0x%x, 0x%x, 0x%x )\n",
782 buf
, buf_len
, addr
);
785 len_in_nibbles
= *buf
& 0x3f;
786 /* despite the fact that X.25 makes us put a length in nibbles
787 * here, the NSAP-addrs are always in full octets
789 switch (*buf
++ & 0xc0) {
791 /* Entire OSI NSAP address */
792 bcopy((caddr_t
)buf
, addr
->siso_data
, addr
->siso_nlen
= buf_len
);
796 /* Partial OSI NSAP address, assume trailing */
797 if (buf_len
+ addr
->siso_nlen
> sizeof(addr
->siso_addr
))
799 bcopy((caddr_t
)buf
, TSEL(addr
), buf_len
);
800 addr
->siso_nlen
+= buf_len
;
804 /* Rather than blow away the connection, just ignore and use
812 register struct sockaddr_iso
*siso
;
814 siso
->siso_len
= sizeof (*siso
);
815 siso
->siso_family
= AF_ISO
;
816 siso
->siso_data
[0] = AFI_37
;
824 * FUNCTION and ARGUMENTS:
825 * Creates a type 37 NSAP in the sockaddr_iso (addr)
826 * from a DTE address found in a sockaddr_x25.
829 * 0 if ok; E* otherwise.
834 struct sockaddr_iso
*addr
;
835 struct sockaddr_x25
*sx
;
837 register char *in
, *out
;
845 src_len
= strlen(in
);
846 addr
->siso_nlen
= (src_len
+ 3) / 2;
847 out
= addr
->siso_data
;
853 for (first
= 0; src_len
> 0; src_len
--) {
854 first
|= 0xf & *in
++;
867 * FUNCTION and ARGUMENTS:
868 * parses (buf_len) bytes beginning at (buf) and finds
869 * a called nsap, a calling nsap, and protocol identifier.
871 * 0 if ok, E* otherwise.
875 parse_facil(lcp
, isop
, buf
, buf_len
)
877 u_char buf_len
; /* in bytes */
882 register u_char
*ptr
= (u_char
*)buf
;
883 u_char
*ptr_lim
, *facil_lim
;
884 int facil_param_len
, facil_len
;
887 printf("parse_facil(0x%x, 0x%x, 0x%x, 0x%x)\n",
888 lcp
, isop
, buf
, buf_len
);
889 dump_buf(buf
, buf_len
);
892 /* find the beginnings of the facility fields in buf
893 * by skipping over the called & calling DTE addresses
894 * i <- # nibbles in called + # nibbles in calling
895 * i += 1 so that an odd nibble gets rounded up to even
896 * before dividing by 2, then divide by two to get # octets
898 i
= (int)(*ptr
>> 4) + (int)(*ptr
&0xf);
901 ptr
++; /* plus one for the DTE lengths byte */
903 /* ptr now is at facil_length field */
905 facil_lim
= ptr
+ facil_len
;
907 printf("parse_facils: facil length is 0x%x\n", (int) facil_len
);
910 while (ptr
< facil_lim
) {
911 /* get NSAP addresses from facilities */
915 facil_param_len
= FACILtoNSAP(isop
->isop_faddr
, ptr
);
919 facil_param_len
= FACILtoNSAP(isop
->isop_laddr
, ptr
);
922 /* from here to default are legit cases that I ignore */
923 /* variable length */
924 case 0xca: /* end-to-end transit delay negot */
925 case 0xc6: /* network user id */
926 case 0xc5: /* charging info : indicating monetary unit */
927 case 0xc2: /* charging info : indicating segment count */
928 case 0xc1: /* charging info : indicating call duration */
929 case 0xc4: /* RPOA extended format */
930 case 0xc3: /* call redirection notification */
935 case 0x0a: /* min. throughput class negot */
936 case 0x02: /* throughput class */
937 case 0x03: case 0x47: /* CUG stuff */
938 case 0x0b: /* expedited data negot */
939 case 0x01: /* Fast select or reverse charging
940 (example of intelligent protocol design) */
941 case 0x04: /* charging info : requesting service */
942 case 0x08: /* called line addr modified notification */
943 case 0x00: /* marker to indicate beginning of CCITT facils */
948 case 0x42: /* pkt size */
949 case 0x43: /* win size */
950 case 0x44: /* RPOA basic format */
951 case 0x41: /* bilateral CUG stuff */
952 case 0x49: /* transit delay selection and indication */
958 "BOGUS FACILITY CODE facil_lim 0x%x facil_len %d, ptr 0x%x *ptr 0x%x\n",
959 facil_lim
, facil_len
, ptr
- 1, ptr
[-1]);
960 /* facil that we don't handle
961 return E_CO_HLI_REJI; */
962 switch (ptr
[-1] & 0xc0) {
963 case 0x00: facil_param_len
= 1; break;
964 case 0x40: facil_param_len
= 2; break;
965 case 0x80: facil_param_len
= 3; break;
966 case 0xc0: facil_param_len
= 0; break;
969 if (facil_param_len
== -1)
970 return E_CO_REG_ICDA
;
971 if (facil_param_len
== 0) /* variable length */
972 facil_param_len
= (int)*ptr
++; /* 1 + the real facil param */
973 ptr
+= facil_param_len
;