* Copyright (c) 1989 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* @(#)cltp_usrreq.c 7.6 (Berkeley) 6/27/91
#ifndef CLTPOVAL_SRC /* XXX -- till files gets changed */
#include "../net/route.h"
* CLTP protocol implementation.
* Per ISO 8602, December, 1987.
cltb
.isop_next
= cltb
.isop_prev
= &cltb
;
cltp_input(m0
, srcsa
, dstsa
, cons_channel
, output
)
struct sockaddr
*srcsa
, *dstsa
;
register struct isopcb
*isop
;
register struct mbuf
*m
= m0
;
register u_char
*up
= mtod(m
, u_char
*);
register struct sockaddr_iso
*src
= (struct sockaddr_iso
*)srcsa
;
int len
, hdrlen
= *up
+ 1, dlen
= 0;
u_char
*uplim
= up
+ hdrlen
;
for (len
= 0; m
; m
= m
->m_next
)
up
+= 2; /* skip header */
while (up
< uplim
) switch (*up
) { /* process options */
src
->siso_len
= up
[1] + TSEL(src
) - (caddr_t
)src
;
if (src
->siso_len
< sizeof(*src
))
src
->siso_len
= sizeof(*src
);
else if (src
->siso_len
> sizeof(*src
)) {
MGET(m
, M_DONTWAIT
, MT_SONAME
);
m
->m_len
= src
->siso_len
;
src
= mtod(m
, struct sockaddr_iso
*);
bcopy((caddr_t
)srcsa
, (caddr_t
)src
, srcsa
->sa_len
);
bcopy((caddr_t
)up
+ 2, TSEL(src
), up
[1]);
up
+= 2 + src
->siso_tlen
;
if (iso_check_csum(m0
, len
)) {
printf("clts: unknown option (%x)\n", up
[0]);
if (dlen
== 0 || src
->siso_tlen
== 0)
for (isop
= cltb
.isop_next
;; isop
= isop
->isop_next
) {
bcmp(TSEL(isop
->isop_laddr
), dtsap
, dlen
) == 0)
if (sbappendaddr(&isop
->isop_socket
->so_rcv
, (struct sockaddr
*)src
,
m
, (struct mbuf
*)0) == 0)
cltpstat
.cltps_ipackets
++;
sorwakeup(isop
->isop_socket
);
if (src
!= (struct sockaddr_iso
*)srcsa
)
* Notify a cltp user of an asynchronous error;
* just wake up so that he can collect error status.
register struct isopcb
*isop
;
sorwakeup(isop
->isop_socket
);
sowwakeup(isop
->isop_socket
);
extern u_char inetctlerrmap
[];
struct sockaddr_iso
*siso
;
if ((unsigned)cmd
> PRC_NCMDS
)
if (sa
->sa_family
!= AF_ISO
&& sa
->sa_family
!= AF_CCITT
)
siso
= (struct sockaddr_iso
*)sa
;
if (siso
== 0 || siso
->siso_nlen
== 0)
case PRC_REDIRECT_TOSNET
:
case PRC_REDIRECT_TOSHOST
:
iso_pcbnotify(&cltb
, siso
,
(int)inetctlerrmap
[cmd
], iso_rtchange
);
if (inetctlerrmap
[cmd
] == 0)
iso_pcbnotify(&cltb
, siso
, (int)inetctlerrmap
[cmd
],
register struct isopcb
*isop
;
register struct sockaddr_iso
*siso
;
int hdrlen
, error
= 0, docsum
;
if (isop
->isop_laddr
== 0 || isop
->isop_faddr
== 0) {
* Calculate data length and get a mbuf for CLTP header.
hdrlen
= 2 + 2 + isop
->isop_laddr
->siso_tlen
+ 2 + isop
->isop_faddr
->siso_tlen
;
if (docsum
= /*isop->isop_flags & CLNP_NO_CKSUM*/ cltp_cksum
)
M_PREPEND(m
, hdrlen
, M_WAIT
);
* Fill in mbuf with extended CLTP header
up
[3] = (siso
= isop
->isop_laddr
)->siso_tlen
;
bcopy(TSEL(siso
), (caddr_t
)up
, siso
->siso_tlen
);
up
[1] = (siso
= isop
->isop_faddr
)->siso_tlen
;
bcopy(TSEL(siso
), (caddr_t
)up
, siso
->siso_tlen
);
* Stuff checksum and output datagram.
iso_gen_csum(m
, 2 + up
- mtod(m
, u_char
*), len
);
cltpstat
.cltps_opackets
++;
return (tpclnp_output(isop
, m
, len
, !docsum
));
/* XXXX should go in iso.h maybe? from tp_param.h, in any case */
u_long cltp_sendspace
= 9216; /* really max datagram size */
u_long cltp_recvspace
= 40 * (1024 + sizeof(struct sockaddr_iso
));
cltp_usrreq(so
, req
, m
, nam
, control
)
struct mbuf
*m
, *nam
, *control
;
struct isopcb
*isop
= sotoisopcb(so
);
return (iso_control(so
, (int)m
, (caddr_t
)nam
,
(struct ifnet
*)control
));
if ((isop
== NULL
&& req
!= PRU_ATTACH
) ||
(control
&& control
->m_len
)) {
error
= iso_pcballoc(so
, &cltb
);
error
= soreserve(so
, cltp_sendspace
, cltp_recvspace
);
error
= iso_pcbbind(isop
, nam
);
error
= iso_pcbconnect(isop
, nam
);
if (isop
->isop_faddr
== 0) {
so
->so_state
&= ~SS_ISCONNECTED
; /* XXX */
* Must block input while temporarily connected.
error
= iso_pcbconnect(isop
, nam
);
if (isop
->isop_faddr
== 0) {
error
= cltp_output(isop
, m
);
iso_getnetaddr(isop
, nam
, TP_LOCAL
);
iso_getnetaddr(isop
, nam
, TP_FOREIGN
);
* stat: don't bother with a blocksize.
return (EOPNOTSUPP
); /* do not free mbuf's */