/* sunlink.c - X.25 abstractions for SunLink X25 */
static char *rcsid
= "$Header: /f/osi/compat/RCS/sunlink.c,v 7.6 91/02/22 09:16:06 mrose Interim $";
* $Header: /f/osi/compat/RCS/sunlink.c,v 7.6 91/02/22 09:16:06 mrose Interim $
* Contributed by John Pavel, Department of Trade and Industry/National
* Physical Laboratory in the UK
* Revision 7.6 91/02/22 09:16:06 mrose
* Revision 7.5 91/01/14 13:33:49 mrose
* Revision 7.4 91/01/07 12:39:59 mrose
* Revision 7.3 90/10/15 18:19:36 mrose
* Revision 7.2 90/07/27 08:41:49 mrose
* Revision 7.1 90/07/09 14:32:22 mrose
* Revision 7.0 89/11/23 21:23:42 mrose
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
/* \f SUN UNIX: SunLink X25 */
void print_x25_facilities ();
int start_x25_client (local
, priv
)
if ((sd
= socket (AF_X25
, SOCK_STREAM
, 0)) == NOTOK
) {
SLOG (compat_log
, LLOG_EXCEPTIONS
, "failed", ("socket"));
int start_x25_server (local
, backlog
, opt1
, opt2
)
if ((sd
= socket (AF_X25
, SOCK_STREAM
, 0)) == NOTOK
) {
SLOG (compat_log
, LLOG_EXCEPTIONS
, "failed", ("socket"));
if (ioctl (sd
, X25_CALL_ACPT_APPROVAL
, (char *) &onoff
) == NOTOK
) {
SLOG (compat_log
, LLOG_EXCEPTIONS
, "failed",
("X25_CALL_ACPT_APPROVAL"));
(void) close_x25_socket (sd
);
if (ioctl (sd
, X25_RD_HOSTADR
, (char *) xs
) == NOTOK
) {
SLOG (compat_log
, LLOG_EXCEPTIONS
, "failed", ("X25_RD_HOSTADR"));
(void) close_x25_socket (sd
);
/* if null DTE in /etc/x25params
then ALWAYS use null DTE for
listen if PID is specified */
if (xs
-> hostlen
== 0 && local
-> na_pidlen
> 0) {
if (local
-> na_pidlen
> NPSIZE
)
local
-> na_pidlen
= NPSIZE
;
*sock
= *xs
; /* struct copy */
bzero((char *) sock
-> data
, NPSIZE
);
bcopy (local
-> na_pid
, (char *) sock
-> data
, local
-> na_pidlen
);
bcopy (local
-> na_cudf
, (char *) sock
-> data
+ NPSIZE
,
sock
-> datalen
= local
-> na_pidlen
+ local
-> na_cudflen
;
sock
= gen2if(local
, sock
, ADDR_LISTEN
);
/* Adopt the convention that if a null DTE is given,
we should get the one from /etc/x25params */
/* Now set the generic local address */
local
= if2gen(local
, xs
, ADDR_LOCAL
);
/* Modified by INRIA to avoid a null local address */
if (bind (sd
, (struct sockaddr
*) sock
, sizeof(CONN_DB
)) == NOTOK
) {
SLOG (compat_log
, LLOG_EXCEPTIONS
, "failed", ("bind"));
(void) close_x25_socket (sd
);
(void) setsockopt (sd
, SOL_SOCKET
, opt1
, NULLCP
, 0);
(void) setsockopt (sd
, SOL_SOCKET
, opt2
, NULLCP
, 0);
(void) setsockopt (sd
, SOL_SOCKET
, opt1
, (char *)&onoff
, sizeof onoff
);
(void) setsockopt (sd
, SOL_SOCKET
, opt2
, (char *)&onoff
, sizeof onoff
);
if (set_x25_facilities(sd
, CALLED
, "Acceptable") == NOTOK
) {
(void) close_x25_socket (sd
);
(void) listen (sd
, backlog
);
int join_x25_server (fd
, remote
)
register struct NSAPaddr
*remote
;
if ((sock
= gen2if (remote
, sock
, ADDR_REMOTE
)) == NULL
)
if (set_x25_facilities(fd
, CALLING
, "Proposed") == NOTOK
)
sock
-> hostlen
|= ANY_LINK
;
if ((nfd
= connect (fd
, (struct sockaddr
*)sock
, sizeof (CONN_DB
)))
if (compat_log
-> ll_events
& LLOG_EXCEPTIONS
)
(void) log_cause_and_diag(fd
); /* Sun's documentation throwns
no light as to whether, or
not this will result in any
if (compat_log
-> ll_events
& LLOG_DEBUG
)
(void) log_x25_facilities(fd
, CALLING
, "Effective Calling");
sock
-> hostlen
&= ~ANY_LINK
;
remote
= if2gen (remote
, sock
, ADDR_REMOTE
);
int join_x25_client (fd
, remote
)
if ((nfd
= accept (fd
, (struct sockaddr
*) sock
, &len
)) == NOTOK
) {
if (compat_log
-> ll_events
& LLOG_EXCEPTIONS
)
(void) log_cause_and_diag(fd
); /* Sun's documentation throwns
no light as to whether, or
not this will result in any
if (compat_log
-> ll_events
& LLOG_DEBUG
)
(void) log_x25_facilities(fd
, CALLED
, "Effective Called");
/* May also need to send call accept packet if using
* FAST_ACPT_CLR, or X25_CALL_ACPT_APPROVAL
* there was a SUNLINK bug in this area
* May as well try it -- if it fails, so what ??
if (ioctl(nfd
,X25_SEND_CALL_ACPT
, NULLCP
) < 0)
SLOG (compat_log
, LLOG_EXCEPTIONS
, "failed", ("X25_SEND_CALL_ACPT"));
remote
= if2gen (remote
, sock
, ADDR_REMOTE
);
/* There is a bug whereby if the thruput is set, calls fail. pb@cl.cam.ac.uk */
int sun_fixed_thruput
= 0;
/* Set up X.25 Facilities. Note that setting even one value causes
the default (/etc/x25params) values to be set explicitly on the
call request (and probably also call accept). This can screw
things up, if your /etc/x25params has not been properly
localised as is normally the case. */
int set_x25_facilities(sd
, coc
, caption
)
bzero ((char *) &facilities
, sizeof facilities
);
&& ioctl (sd
, X25_RD_FACILITY
, (char *) &facilities
) == NOTOK
) {
SLOG (compat_log
, LLOG_EXCEPTIONS
, "failed", ("X25_RD_FACILITY"));
|| reverse_charge
|| recvpktsize
|| sendpktsize
|| recvwndsize
|| sendwndsize
|| recvthruput
|| sendthruput
|| cug_req
/* || cug_index */
|| fast_select_type
|| rpoa_req
/* || rpoa */)) {
if (facilities
.recvpktsize
)
recvpktsize
= facilities
.recvpktsize
;
if (facilities
.sendpktsize
)
sendpktsize
= facilities
.sendpktsize
;
facilities
.reverse_charge
= reverse_charge
;
facilities
.recvpktsize
= recvpktsize
;
facilities
.sendpktsize
= sendpktsize
;
facilities
.recvwndsize
= recvwndsize
;
facilities
.sendwndsize
= sendwndsize
;
if (sun_fixed_thruput
) { /* get round Sun bug */
facilities
.recvthruput
= recvthruput
;
facilities
.sendthruput
= sendthruput
;
facilities
.recvthruput
= facilities
.sendthruput
= 0;
facilities
.cug_req
= cug_req
;
facilities
.cug_index
= cug_index
;
facilities
.fast_select_type
= fast_select_type
;
/* May as well accept FCS calls */
facilities
.fast_select_type
= FAST_ACPT_CLR
;
facilities
.rpoa_req
= rpoa_req
;
#define DO_NOT_USE_FACILITIES
#ifndef DO_NOT_USE_FACILITIES
if (compat_log
-> ll_events
& LLOG_DEBUG
)
print_x25_facilities (facilities
, coc
, caption
);
if (ioctl (sd
, X25_WR_FACILITY
, (char *) &facilities
) == NOTOK
) {
SLOG (compat_log
, LLOG_EXCEPTIONS
, "failed", ("X25_WR_FACILITY"));
if (facilities
.recvpktsize
)
recvpktsize
= facilities
.recvpktsize
;
if (facilities
.sendpktsize
)
sendpktsize
= facilities
.sendpktsize
;
int log_cause_and_diag(fd
)
if (ioctl(fd
, X25_RD_CAUSE_DIAG
, (char *) &diag
) == NOTOK
) {
SLOG (compat_log
, LLOG_EXCEPTIONS
, "failed", ("X25_RD_CAUSE_DIAG"));
return elucidate_x25_err ((int) diag
.flags
, (char *) diag
.data
);
static int log_x25_facilities (fd
, coc
, caption
)
if (ioctl (fd
, X25_RD_FACILITY
, (char *) &f
) == NOTOK
) {
SLOG (compat_log
, LLOG_EXCEPTIONS
, "failed", ("X25_RD_FACILITY"));
print_x25_facilities (f
, coc
, caption
);
static void print_x25_facilities (f
, coc
, caption
)
DLOG (compat_log
, LLOG_DEBUG
, ("%s X.25 Facilities:", caption
));
switch (f
.reverse_charge
) {
DLOG (compat_log
, LLOG_DEBUG
, ((coc
== CALLED
)
? "reverse charging not requested"
: "reverse charging not allowed"));
DLOG (compat_log
, LLOG_DEBUG
, ((coc
== CALLING
)
? "reverse charging requested"
: "reverse charging allowed"));
DLOG (compat_log
, LLOG_DEBUG
, ("invalid reverse_charge: %d",
DLOG (compat_log
, LLOG_DEBUG
, ("default recv packet size"));
DLOG (compat_log
, LLOG_DEBUG
, ("recv packet size %d",
DLOG (compat_log
, LLOG_DEBUG
, ("invalid recv packet size %d",
DLOG (compat_log
, LLOG_DEBUG
, ("default send packet size"));
DLOG (compat_log
, LLOG_DEBUG
, ("send packet size %d",
DLOG (compat_log
, LLOG_DEBUG
, ("invalid send packet size %d",
DLOG (compat_log
, LLOG_DEBUG
,
(f
.recvwndsize
== 0 ? "default recv window size"
: 1 <= f
.recvwndsize
&& f
.recvwndsize
<= 127
: "invalid recv window size %d",
DLOG (compat_log
, LLOG_DEBUG
,
(f
.sendwndsize
== 0 ? "default send window size"
: 1 <= f
.sendwndsize
&& f
.sendwndsize
<= 127
: "invalid send window size %d",
DLOG (compat_log
, LLOG_DEBUG
, ("default recv throughput"));
DLOG (compat_log
, LLOG_DEBUG
, ("recv throughput %dbps", baud
));
DLOG (compat_log
, LLOG_DEBUG
, ("invalid recv throughput %d",
DLOG (compat_log
, LLOG_DEBUG
, ("default send throughput"));
DLOG (compat_log
, LLOG_DEBUG
, ("send throughput %dbps", baud
));
DLOG (compat_log
, LLOG_DEBUG
, ("invalid send throughput %d",
DLOG (compat_log
, LLOG_DEBUG
, ("no closed user group"));
DLOG (compat_log
, LLOG_DEBUG
, ("closed user group 0x%x (BCD)",
DLOG (compat_log
, LLOG_DEBUG
, ("invalid closed user group %d",
switch (f
.fast_select_type
) {
DLOG (compat_log
, LLOG_DEBUG
, ("don't use fast select"));
DLOG (compat_log
, LLOG_DEBUG
, ("clear is fast select response"));
DLOG (compat_log
, LLOG_DEBUG
,
("clear or call accepted is fast select response"));
DLOG (compat_log
, LLOG_DEBUG
, ("invalid fast select type %d",
DLOG (compat_log
, LLOG_DEBUG
, ("no RPOA transit request"));
DLOG (compat_log
, LLOG_DEBUG
, ("RPOA transit request 0x%x",
DLOG (compat_log
, LLOG_DEBUG
, ("invalid RPOA transit request %d",