cots(7) CLIX cots(7)
NAME
cots - ISO/OSI Transport Layer Class 4 Protocol/Internetwork Protocol
STREAMS multiplexer driver
DESCRIPTION
The cots driver is a ``cloneable'' (see clone) STREAMS multiplexing driver
that provides the services of the ISO/OSI transport layer class 4 and ISO
Internetwork Protocol (IP).
The cots driver communicates using the AT&T Transport Provider Interface
(TPI). Using TPI allows applications to interface with cots using the
AT&T Transport Layer Interface (TLI). The driver provides the TLI network
service type T_COTS, a connection-oriented protocol service without
orderly release. The tp4 transport protocols and connectionless network
procotols (clnp) reside within the cots multiplexing driver.
The cots/clnp should be linked above the dlpi STREAMS driver that has been
bound to the Logical Link Class 1 (LLC1) Link Service Access Point (LSAP)
(such as 0xFE) to provide the cots/clnp/llc1 functionality in accordance
with US GOSIP version 1. The osid daemon performs this binding at boot
time.
The cots address is represented in the following structure type:
struct netbuf {
unsigned maxlen;
unsigned len;
char *buf;
};
The maxlen member in the above should be greater or equal to the number of
bytes in buf. The len member should be the number of bytes in buf.
The buf parameter should point to one of the following transport address
types depending on the TLI call used:
This structure is used in the t_bind() request:
typedef struct {
unsigned len; /* length of address field */
unsigned char addr[32]; /* the address field */
} tsap_selector;
typedef struct {
unsigned len; /* length of address field */
unsigned char addr[20]; /* binary representation of
address */
} nsap_address;
2/94 - Intergraph Corporation 1
cots(7) CLIX cots(7)
This structure is specified in the t_connect() request and returned in the
t_listen() call:
typedef struct {
tsap_selector tsap; /* Transport SAP ID */
nsap_address nsap; /* Network SAP address */
} tsap_address;
The following functions can be invoked when using the cots interface:
The t_open() function creates a logical device for the user to communicate
with the local tp4 entity. The user should specify /dev/cots as the
device name when using t_open().
The t_bind() function informs cots of the local tsap selector to be
associated with the stream. The t_bind() request contains tsap_selector
in the address specification.
The t_unbind() function disassociates a transport endpoint created by
t_bind().
The t_close() function closes the logical device associated with the cots
endpoint created by calling t_open().
The t_getinfo() function works as specified in TLI and TPI.
The t_connect() function opens a transport connection with a remote
entity. The t_connect() function contains the tsap_address in the address
specification.
The t_listen() function waits for a connection indication from a remote
cots entity. This function returns a tsap_address in the address
specification.
The t_accept() function accepts a connection indication from a remote
entity.
The t_snd() function sends normal or expedited data through an established
cots connection.
The t_rcv() function receives normal or expedited data from an established
cots connection. If the T_MORE flag is set, the user needs to issue
another t_rcv() function to receive the remainder of a packet.
The t_snddis() function uses the first longword in the udata field of the
t_call() argument to t_snddis() to specify one of the following values as
the disconnect reason:
1 Congestion at tsap.
2 Session entity not attached to tsap.
2 Intergraph Corporation - 2/94
cots(7) CLIX cots(7)
128 Normal disconnect initiated by session entity.
133 Protocol error.
The t_rcvdis() function receives an indication that the remote cots entity
rejected a proposed connection or simply aborted the connection.
EXAMPLES
The following examples represent sample programs that use the cots
interface. Example 1 is a server program and Example 2 is a client
program.
1. Example 1: Server Example 1: Server
#include <stdio.h>
#include <tiuser.h>
#include <fcntl.h>
#include <stropts.h>
typedef struct {
unsigned int len; /* length of address field */
unsigned char addr[NSAPSZ]; /* binary representation
of address */
} nsap_address;
typedef struct {
unsigned len; /* length of address field */
unsigned char addr[TSAPSZ]; /* the address field */
} tsap_selector;
/*
* Transport SAP address.
*/
typedef struct {
tsap_selector tsap; /* Transport SAP id */
nsap_address nsap; /* Network SAP address */
} tsap_address;
struct test_type {
int type;
int bufsize;
};
/** Allowable types **/
#define ECHO_SRV 1
#define DEFAULT_SRV 0
#define MAXBUFSZ 16*1024
2/94 - Intergraph Corporation 3
cots(7) CLIX cots(7)
char rdata_buf[MAXBUFSZ];
tsap_address remaddr;
int bufsize, echo;
main()
{
int fd;
struct t_discon *discon;
struct t_call *call;
extern int t_errno;
struct t_bind *bind;
int nbytes, i, flags = 0;
struct test_type type;
char *cp;
/*
** Transport layer
*/
if ((fd = t_open("/dev/cots", O_RDWR, NULL)) < 0) {
t_error("/dev/cots t_open failed");
exit(1);
}
/*
* Bind local TSAP
*/
if ((bind = (struct t_bind *) t_alloc(fd, T_BIND,
T_ALL)) == NULL) {
t_error("cots t_bind failed");
exit(2);
}
cp = (char *)bind->addr.buf;
*cp++ = 0; /* NSAP address size = 0 */
*cp++ = 1; /* TSAP selector size */
*cp = 0xb; /* TSAP selector */
bind->addr.len = 3;
bind->qlen = 1;
if (t_bind(fd, bind, bind) < 0) {
t_error("t_bind failed");
exit (3);
}
/*
* Get a connection established
*/
if ((call = (struct t_call *)t_alloc(fd, T_CALL,
T_ALL)) == NULL) {
t_error("t_alloc of t_call struct failed");
exit(3);
}
4 Intergraph Corporation - 2/94
cots(7) CLIX cots(7)
if (t_listen(fd, call) < 0) {
t_error("t_listen failed for listen_fd");
exit(6);
}
if (t_accept(fd, fd, call) < 0) {
if (t_errno == TLOOK) {
if (t_close(fd) < 0) {
t_error("t_close failed for listen_fd");
exit(10);
}
}
t_error ("t_accept failed");
exit(7);
}
if ((nbytes = t_rcv(fd, &type, sizeof(struct test_type),
&flags)) < 0) {
if (t_errno == TLOOK) {
printf("could not get buffer size from initiator0);
}
t_error("t_rcv failed for fd");
exit(8);
}
if (nbytes != sizeof(struct test_type)) {
printf("type packet error0);
exit(1);
}
bufsize = type.bufsize;
echo = type.type;
for (i = 0; ; i++)
{
if ((nbytes = t_rcv(fd, rdata_buf, bufsize,
&flags)) < 0) {
if (t_errno == TLOOK) {
switch (t_look(fd)) {
default:
printf("t_look() returns an unexpected event0);
exit(7);
case T_ERROR:
printf("t_look() returns T_ERROR0);
exit(8);
case -1:
t_error("t_look() failed0);
exit(9);
case 0:
fprintf(stderr, "t_look() return no event0);
exit(10);
2/94 - Intergraph Corporation 5
cots(7) CLIX cots(7)
case T_DISCONNECT:
discon = (struct t_discon *)t_alloc(fd,
T_DIS, T_ALL);
if (t_rcvdis(fd, discon) < 0) {
printf("t_rcvdis() failed,
errno: %d0, t_errno);
}
exit(0);
}
}
}
}
}
2. Example 2: Client
#include <stdio.h>
#include <tiuser.h>
#include <fcntl.h>
#include <stropts.h>
typedef struct {
unsigned int len; /* length of address field */
unsigned char addr[NSAPSZ]; /* binary representation of address */
} nsap_address;
typedef struct {
unsigned len; /* length of address field */
unsigned char addr[TSAPSZ]; /* the address field */
} tsap_selector;
/*
* Transport SAP address.
*/
typedef struct {
tsap_selector tsap; /* Transport SAP id */
nsap_address nsap; /* Network SAP address */
} tsap_address;
struct test_type {
int type;
int bufsize;
};
#define MAXBUFSZ 16*1024
char data_buf[MAXBUFSZ];
tsap_address remaddr;
6 Intergraph Corporation - 2/94
cots(7) CLIX cots(7)
int bufsize, echo, nloop;
main()
{
int fd;
struct t_call *call;
extern int t_errno;
struct t_bind *bind;
int nbytes, i, timer, tbytes;
struct test_type type;
char *cp;
/*
** Transport layer
*/
if ((fd = t_open("/dev/cots", O_RDWR, NULL)) < 0) {
t_error("/dev/cots t_open failed");
exit(1);
}
/*
* Bind local TSAP
*/
if ((bind = (struct t_bind *) t_alloc(fd, T_BIND,
T_ALL)) == NULL) {
t_error("cots t_bind failed");
exit(2);
}
bind->addr.len = sizeof (tsap_selector);
cp = (char *) bind->addr.buf;
*cp++ = 0; /* NSAP address size = 0 */
*cp++ = 1; /* TSAP selector size */
*cp = 0xa; /* TSAP selector */
bind->addr.len = 3;
if (t_bind(fd, bind, bind) < 0) {
t_error("t_bind failed");
exit (3);
}
t_free(bind);
remaddr.tsap.len = 1;
remaddr.tsap.addr[0] = 0xb;
remaddr.nsap.len = 14;
remaddr.nsap.addr[0] = 0x47;
remaddr.nsap.addr[1] = 0x00;
remaddr.nsap.addr[2] = 0x04;
remaddr.nsap.addr[3] = 0x00;
remaddr.nsap.addr[4] = 0x3d;
remaddr.nsap.addr[5] = 0x00;
2/94 - Intergraph Corporation 7
cots(7) CLIX cots(7)
remaddr.nsap.addr[6] = 0x01;
remaddr.nsap.addr[7] = 0x00;
remaddr.nsap.addr[8] = 0x00;
remaddr.nsap.addr[9] = 0x00;
remaddr.nsap.addr[10] = 0x00;
remaddr.nsap.addr[11] = 0x00;
remaddr.nsap.addr[12] = 0x04;
remaddr.nsap.addr[13] = 0x01;
/*
* Get a connection established
*/
if ((call = (struct t_call *)t_alloc(fd, T_CALL,
T_ALL)) == NULL) {
t_error("t_alloc of t_call struct failed");
exit(3);
}
cp = (char *)call->addr.buf;
*cp++ = remaddr.nsap.len;
for (i = 0; i < remaddr.nsap.len; i++)
*cp++ = remaddr.nsap.addr[i];
*cp++ = remaddr.tsap.len;
for (i = 0; i < remaddr.tsap.len; i++)
*cp++ = remaddr.tsap.addr[i];
call->addr.len = remaddr.nsap.len + remaddr.tsap.len + 2;
if (t_connect(fd, call, NULL) < 0) {
t_error("t_connect failed");
exit(4);
}
for (i = 0; i < bufsize; i++)
data_buf[i] = 0xEE;
/*
* Send type of test to be made and buffer size to be used
* in the test */
type.bufsize = bufsize = 1024;
echo = 0;
type.type = (echo ? ECHO_SRV : DEFAULT_SRV);
if ((nbytes = t_snd(fd, &type, sizeof(struct test_type), 0)) !=
sizeof(struct test_type)) {
printf("could not send size of buffers to be used0);
t_error("t_snd failed for fd");
exit(5);
}
tbytes = 0;
timer = time(NULL);
8 Intergraph Corporation - 2/94
cots(7) CLIX cots(7)
for (i = 0; i < 10; i++)
{
if ((nbytes = t_snd(fd, data_buf, bufsize, 0)) < 0) {
t_error("t_snd failed for fd");
exit(5);
}
if (nbytes != bufsize) {
printf("sent %d bytes instead of %d0,
nbytes, bufsize);
continue;
}
else tbytes += nbytes;
}
if (t_snddis(fd, call) < 0) {
printf("t_snddis() failed, errno: %d0, t_errno);
}
printf("total number of bytes %d in %d sec.0,
tbytes, time(NULL) - timer);
}
RELATED INFORMATION
AT&T UNIX System V STREAMS Programmer's Guide, AT&T UNIX System V Network
Programmer's Guide
2/94 - Intergraph Corporation 9