/* ts2tcp.c - TPM: TCP interface */
static char *rcsid
= "$Header: /f/osi/tsap/RCS/ts2tcp.c,v 7.8 91/02/22 09:47:23 mrose Interim $";
* $Header: /f/osi/tsap/RCS/ts2tcp.c,v 7.8 91/02/22 09:47:23 mrose Interim $
* Revision 7.8 91/02/22 09:47:23 mrose
* Revision 7.7 90/12/11 10:51:46 mrose
* Revision 7.6 90/10/16 16:24:17 mrose
* Revision 7.5 90/07/09 14:51:21 mrose
* Revision 7.4 90/03/23 17:31:28 mrose
* Revision 7.3 90/02/19 13:07:26 mrose
* Revision 7.2 89/12/08 09:41:39 mrose
* Revision 7.1 89/12/07 01:07:36 mrose
* Revision 7.0 89/11/23 22:30:40 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
#define MAX1006 2048 /* could be as high as TPKT_MAXLEN */
#if defined(FIONBIO) || defined(O_NDELAY)
static fd_set inprogress
;
static struct sockaddr_in
*peers
= NULL
;
/* \f N-CONNECT.REQUEST */
int tcpopen (tb
, local
, remote
, td
, async
)
register struct tsapblk
*tb
;
struct TSAPdisconnect
*td
;
struct sockaddr_in lo_socket
,
register struct sockaddr_in
*lsock
= &lo_socket
,
register struct hostent
*hp
;
register struct servent
*sp
;
return tsaplose (td
, DR_PARAMETER
, NULLCP
,
"asynchronous not supported");
bzero ((char *) isock
, sizeof *isock
);
if (remote
-> na_port
== 0) {
if ((sp
= getservbyname ("tsap", "tcp")) == NULL
)
sp
= getservbyname ("iso-tsap", "tcp");
isock
-> sin_port
= sp
? sp
-> s_port
: htons ((u_short
) 102);
isock
-> sin_port
= remote
-> na_port
;
if ((hp
= gethostbystring (remote
-> na_domain
)) == NULL
)
return tsaplose (td
, DR_ADDRESS
, NULLCP
, "%s: unknown host",
(void) strncpy (remote
-> na_domain
, hp
-> h_name
,
sizeof remote
-> na_domain
);
isock
-> sin_family
= hp
-> h_addrtype
;
(void) strcpy (remote
-> na_domain
, inet_ntoa (isock
-> sin_addr
));
if (local
&& local
-> na_domain
[0]) {
bzero ((char *) lsock
, sizeof *lsock
);
if ((hp
= gethostbystring (local
-> na_domain
)) == NULL
)
return tsaplose (td
, DR_ADDRESS
, NULLCP
, "%s: unknown host",
if ((lsock
-> sin_family
= hp
-> h_addrtype
) != isock
-> sin_family
)
return tsaplose (td
, DR_ADDRESS
, NULLCP
,
"address family mismatch");
if ((fd
= start_tcp_client (lsock
, 0)) == NOTOK
)
return tsaplose (td
, DR_CONGEST
, "socket", "unable to start");
(void) ioctl (fd
, FIONBIO
, (onoff
= 1, (char *) &onoff
));
(void) fcntl (fd
, F_SETFL
, O_NDELAY
);
if (join_tcp_server (fd
, isock
) == NOTOK
) {
peers
= (struct sockaddr_in
*)
calloc ((unsigned) getdtablesize (),
(void) tsaplose (td
, DR_CONGEST
, NULLCP
,
(void) close_tcp_socket (fd
);
return (tb
-> tb_fd
= NOTOK
);
FD_SET (fd
, &inprogress
);
peers
[fd
] = *isock
;/* struct copy */
(void) tsaplose (td
, DR_REFUSED
, "connection", "unable to establish");
(void) close_tcp_socket (fd
);
return (tb
-> tb_fd
= NOTOK
);
(void) ioctl (fd
, FIONBIO
, (onoff
= 0, (char *) &onoff
));
(void) fcntl (fd
, F_SETFL
, 0x00);
static int tcpretry (tb
, td
)
struct TSAPdisconnect
*td
;
struct sockaddr_in
*isock
= &peers
[fd
];
if (xselect (fd
+ 1, NULLFD
, &mask
, NULLFD
, 0) < 1)
if (!FD_ISSET (fd
, &inprogress
))
if (join_tcp_server (fd
, isock
) == NOTOK
) {
case EINVAL
: /* UNIX bug: could be any socket errno, e.g.,
(void) tsaplose (td
, DR_REFUSED
, "connection", "unable to establish");
FD_CLR (fd
, &inprogress
);
(void) close_tcp_socket (fd
);
return (tb
-> tb_fd
= NOTOK
);
(void) ioctl (fd
, FIONBIO
, (onoff
= 0, (char *) &onoff
));
(void) fcntl (fd
, F_SETFL
, 0x00);
FD_CLR (fd
, &inprogress
);
return tsaplose (td
, DR_OPERATION
, NULLCP
, "connection not in progress");
/* \f init for read from network */
register struct tsapkt
*t
;
for (bp
= (char *) &t
-> t_pkthdr
, i
= TPKT_HDRLEN (t
);
switch (cc
= read_tcp_socket (fd
, bp
, i
)) {
if (t
-> t_vrsn
!= TPKT_VRSN
)
if ((t
-> t_length
= ntohs (t
-> t_length
)) < TPKT_HDRLEN (t
))
char *tcpsave (fd
, cp1
, cp2
, td
)
struct TSAPdisconnect
*td
;
static char buffer
[BUFSIZ
];
(void) sprintf (buffer
, "%c%d %s %s", NT_TCP
, fd
, cp1
, cp2
);
int tcprestore (tb
, buffer
, td
)
register struct tsapblk
*tb
;
struct TSAPdisconnect
*td
;
char domain1
[NSAP_DOMAINLEN
+ 1 + 5 + 1],
domain2
[NSAP_DOMAINLEN
+ 1 + 5 + 1];
register struct NSAPaddr
*na
;
register struct tsapADDR
*ta
;
ta
= &tb
-> tb_initiating
;
na
-> na_community
= ts_comm_tcp_default
;
if (sscanf (buffer
, "%d %s %s", &fd
, domain1
, domain2
) != 3 || fd
< 0)
return tsaplose (td
, DR_PARAMETER
, NULLCP
,
"bad initialization vector \"%s\"", buffer
);
if (cp
= index (domain1
, '+')) {
na
-> na_port
= htons ((u_short
) atoi (cp
));
(void) strncpy (na
-> na_domain
, domain1
, sizeof na
-> na_domain
);
ta
= &tb
-> tb_responding
;
na
-> na_community
= ts_comm_tcp_default
;
if (cp
= index (domain2
, '+')) {
na
-> na_port
= htons ((u_short
) atoi (cp
));
(void) strncpy (na
-> na_domain
, domain2
, sizeof na
-> na_domain
);
register struct tsapblk
*tb
;
tb
-> tb_flags
|= TB_TCP
;
tb
-> tb_tsdusize
= MAX1006
- (tb
-> tb_tpduslop
= sizeof t
-> t_pkthdr
+ DT_MAGIC
);
tb
-> tb_retryfnx
= tcpretry
;
tb
-> tb_initfnx
= tcpinit
;
tb
-> tb_readfnx
= read_tcp_socket
;
tb
-> tb_writefnx
= tp0write
;
tb
-> tb_closefnx
= close_tcp_socket
;
tb
-> tb_selectfnx
= select_tcp_socket
;