1 /* $NetBSD: cltp_usrreq.c,v 1.33 2008/04/24 11:38:38 ad Exp $ */
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * @(#)cltp_usrreq.c 8.1 (Berkeley) 6/10/93
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: cltp_usrreq.c,v 1.33 2008/04/24 11:38:38 ad Exp $");
37 #ifndef CLTPOVAL_SRC /* XXX -- till files gets changed */
38 #include <sys/param.h>
39 #include <sys/malloc.h>
41 #include <sys/protosw.h>
42 #include <sys/socket.h>
43 #include <sys/socketvar.h>
44 #include <sys/errno.h>
46 #include <sys/systm.h>
50 #include <net/route.h>
52 #include <netiso/argo_debug.h>
53 #include <netiso/iso.h>
54 #include <netiso/iso_pcb.h>
55 #include <netiso/iso_var.h>
56 #include <netiso/clnp.h>
57 #include <netiso/cltp_var.h>
58 #include <netiso/tp_param.h>
59 #include <netiso/tp_var.h>
61 #include <machine/stdarg.h>
66 * CLTP protocol implementation.
67 * Per ISO 8602, December, 1987.
73 cltb
.isop_next
= cltb
.isop_prev
= &cltb
;
78 struct cltpstat cltpstat
;
83 cltp_input(struct mbuf
*m0
, ...)
85 struct sockaddr
*srcsa
, *dstsa
;
89 struct mbuf
*m_src
= 0;
90 u_char
*up
= mtod(m
, u_char
*);
91 struct sockaddr_iso
*src
;
92 int len
, hdrlen
= *up
+ 1, dlen
= 0;
93 u_char
*uplim
= up
+ hdrlen
;
98 srcsa
= va_arg(ap
, struct sockaddr
*);
99 dstsa
= va_arg(ap
, struct sockaddr
*);
100 cons_channel
= va_arg(ap
, int);
102 src
= satosiso(srcsa
);
104 for (len
= 0; m
; m
= m
->m_next
)
106 up
+= 2; /* skip header */
108 switch (*up
) { /* process options */
110 src
->siso_tlen
= up
[1];
111 src
->siso_len
= up
[1] +
112 ((const char *)TSEL(src
) - (const char *)src
);
113 if (src
->siso_len
< sizeof(*src
))
114 src
->siso_len
= sizeof(*src
);
115 else if (src
->siso_len
> sizeof(*src
)) {
116 MGET(m_src
, M_DONTWAIT
, MT_SONAME
);
119 m_src
->m_len
= src
->siso_len
;
120 src
= mtod(m_src
, struct sockaddr_iso
*);
121 bcopy((void *) srcsa
, (void *) src
, srcsa
->sa_len
);
123 memcpy(WRITABLE_TSEL(src
), (char *)up
+ 2, up
[1]);
124 up
+= 2 + src
->siso_tlen
;
128 dtsap
= 2 + (char *)up
;
134 if (iso_check_csum(m0
, len
)) {
135 cltpstat
.cltps_badsum
++;
142 printf("clts: unknown option (%x)\n", up
[0]);
143 cltpstat
.cltps_hdrops
++;
146 if (dlen
== 0 || src
->siso_tlen
== 0)
148 for (isop
= cltb
.isop_next
;; isop
= isop
->isop_next
) {
150 cltpstat
.cltps_noport
++;
153 if (isop
->isop_laddr
&&
154 bcmp(TSEL(isop
->isop_laddr
), dtsap
, dlen
) == 0)
160 if (sbappendaddr(&isop
->isop_socket
->so_rcv
, sisotosa(src
), m
,
161 (struct mbuf
*) 0) == 0)
163 cltpstat
.cltps_ipackets
++;
164 sorwakeup(isop
->isop_socket
);
167 if (src
!= satosiso(srcsa
))
174 * Notify a cltp user of an asynchronous error;
175 * just wake up so that he can collect error status.
182 sorwakeup(isop
->isop_socket
);
183 sowwakeup(isop
->isop_socket
);
189 const struct sockaddr
*sa
,
192 const struct sockaddr_iso
*siso
;
194 if ((unsigned)cmd
>= PRC_NCMDS
)
196 if (sa
->sa_family
!= AF_ISO
&& sa
->sa_family
!= AF_CCITT
)
198 siso
= satocsiso(sa
);
199 if (siso
== 0 || siso
->siso_nlen
== 0)
204 case PRC_REDIRECT_NET
:
205 case PRC_REDIRECT_HOST
:
206 case PRC_REDIRECT_TOSNET
:
207 case PRC_REDIRECT_TOSHOST
:
208 iso_pcbnotify(&cltb
, siso
,
209 (int) isoctlerrmap
[cmd
], iso_rtchange
);
213 if (isoctlerrmap
[cmd
] == 0)
215 iso_pcbnotify(&cltb
, siso
, (int) isoctlerrmap
[cmd
],
221 cltp_output(struct mbuf
*m
, ...)
225 struct sockaddr_iso
*siso
;
226 int hdrlen
, error
= 0, docsum
;
231 isop
= va_arg(ap
, struct isopcb
*);
234 if (isop
->isop_laddr
== 0 || isop
->isop_faddr
== 0) {
239 * Calculate data length and get a mbuf for CLTP header.
241 hdrlen
= 2 + 2 + isop
->isop_laddr
->siso_tlen
242 + 2 + isop
->isop_faddr
->siso_tlen
;
243 docsum
= /* isop->isop_flags & CLNP_NO_CKSUM */ cltp_cksum
;
246 M_PREPEND(m
, hdrlen
, M_WAIT
);
247 len
= m
->m_pkthdr
.len
;
249 * Fill in mbuf with extended CLTP header
251 up
= mtod(m
, u_char
*);
253 up
[1] = UD_TPDU_type
;
254 up
[2] = CLTPOVAL_SRC
;
255 up
[3] = (siso
= isop
->isop_laddr
)->siso_tlen
;
257 bcopy(TSEL(siso
), (void *) up
, siso
->siso_tlen
);
258 up
+= siso
->siso_tlen
;
259 up
[0] = CLTPOVAL_DST
;
260 up
[1] = (siso
= isop
->isop_faddr
)->siso_tlen
;
262 bcopy(TSEL(siso
), (void *) up
, siso
->siso_tlen
);
264 * Stuff checksum and output datagram.
267 up
+= siso
->siso_tlen
;
268 up
[0] = CLTPOVAL_CSM
;
270 iso_gen_csum(m
, 2 + up
- mtod(m
, u_char
*), len
);
272 cltpstat
.cltps_opackets
++;
273 return (tpclnp_output(m
, len
, isop
, !docsum
));
279 u_long cltp_sendspace
= 9216; /* really max datagram size */
280 u_long cltp_recvspace
= 40 * (1024 + sizeof(struct sockaddr_iso
));
281 /* 40 1K datagrams */
286 cltp_usrreq(so
, req
, m
, nam
, control
, l
)
289 struct mbuf
*m
, *nam
, *control
;
296 if (req
== PRU_CONTROL
)
297 return (iso_control(so
, (long)m
, (void *)nam
,
298 (struct ifnet
*)control
, l
));
300 if (req
== PRU_PURGEIF
) {
301 mutex_enter(softnet_lock
);
302 iso_purgeif((struct ifnet
*)control
);
303 mutex_exit(softnet_lock
);
308 isop
= sotoisopcb(so
);
310 if (req
!= PRU_SEND
&& req
!= PRU_SENDOOB
&& control
)
311 panic("cltp_usrreq: unexpected control mbuf");
313 if (isop
== 0 && req
!= PRU_ATTACH
) {
326 if (so
->so_snd
.sb_hiwat
== 0 || so
->so_rcv
.sb_hiwat
== 0) {
327 error
= soreserve(so
, cltp_sendspace
, cltp_recvspace
);
331 error
= iso_pcballoc(so
, &cltb
);
341 error
= iso_pcbbind(isop
, nam
, l
);
349 error
= iso_pcbconnect(isop
, nam
, l
);
360 soisdisconnected(so
);
361 iso_pcbdisconnect(isop
);
373 if (control
&& control
->m_len
) {
380 if ((so
->so_state
& SS_ISCONNECTED
) != 0) {
384 error
= iso_pcbconnect(isop
, nam
, l
);
391 if ((so
->so_state
& SS_ISCONNECTED
) == 0) {
396 error
= cltp_output(m
, isop
);
398 iso_pcbdisconnect(isop
);
403 * stat: don't bother with a blocksize.
419 iso_getnetaddr(isop
, nam
, TP_LOCAL
);
423 iso_getnetaddr(isop
, nam
, TP_FOREIGN
);
427 panic("cltp_usrreq");