Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought



  cox(7)                              CLIX                              cox(7)



  NAME

    cox - ISO/OSI Transport Layer Class 0/2/4 Protocol/Internetwork Protocol
    STREAMS multiplexer driver

  DESCRIPTION

    The cox driver is a ``cloneable'' (see clone) STREAMS multiplexing driver
    that provides the services of the ISO/OSI transport layer class /0/2/4 and
    ISO Internetwork Protocol (IP).

    The cox driver communicates using the AT&T Transport Provider Interface
    (TPI).  Using TPI allows applications to interface with cox 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 transport protocols and connection-oriented network
    procotols (cons) reside within the cox multiplexing driver.

    The cox/cons should be linked above the X25 STREAMS driver.  The osid
    daemon performs this binding at boot time.

    The cox 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 member should point to one of the following transport address
    types depending on the TLI call used: (Note that the nsap address should
    be the same as the DTE address defined in /etc/configx25.dat.)

    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;

    This structure is specified in the t_connect() request and returned in the
    t_listen() call:



  2/94 - Intergraph Corporation                                              1






  cox(7)                              CLIX                              cox(7)



    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 cox interface:

    The t_open() function creates a logical device for the user to communicate
    with the local cox entity.  The user should specify /dev/cox as the device
    name when using t_open().

    The t_bind() function informs cox 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 cox
    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 DTE_address in the address
    specification.

    The t_listen() function waits for a connection indication from a remote
    cox entity.  This function returns a DTE_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
    cox connection.

    The t_rcv() function receives normal or expedited data from an established
    cox 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.

    128   Normal disconnect initiated by session entity.




  2                                              Intergraph Corporation - 2/94






  cox(7)                              CLIX                              cox(7)



    133   Protocol error.

    The t_rcvdis() function receives an indication that the remote cox entity
    rejected a proposed connection or simply aborted the connection.

  EXAMPLES

    1.  The following example is an example of a server program:

        #include <stdio.h>
        #include <tiuser.h>
        #include <fcntl.h>
        #include <stropts.h>

        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;

        typedef struct {
             tsap_selector tsap; /* Transport SAP ID */
             nsap_address  nsap; /* Network SAP address */
        } tsap_address;

        #define verbose  1       /* 1 on 0 off */
        #define bufsize  1024
        #define MAXBUFSZ 4*1024

        extern int t_errno;
        char data_buf[MAXBUFSZ];
        char rdata_buf[MAXBUFSZ];
        tsap_address *remaddr;

        main()
        {
             int fd, nbytes, i, flags;
             struct t_call *call;
             struct t_bind *bind;
             tsap_selector *loctsap;

             if ((fd = t_open("/dev/cox", O_RDWR, NULL)) < 0) {
                  t_error("/dev/cox t_open failed");
                  exit(1);
             }




  2/94 - Intergraph Corporation                                              3






  cox(7)                              CLIX                              cox(7)



             /* Bind local to TSAP 0009*/
             if ((bind = (struct t_bind *) t_alloc(fd, T_BIND,
               T_ALL)) == NULL) {
                  t_error("cox t_bind failed");
                  t_close(fd); exit(2);
             }
             bind->addr.len = sizeof (tsap_selector);
             loctsap = (tsap_selector *) bind->addr.buf;
             loctsap->len = 2; loctsap->addr[0] = 0x0;
                   loctsap->addr[1] = 0x9;
             bind->qlen = 1; /* passive */
             if (t_bind(fd, bind, bind) < 0) {
                  t_error("t_bind failed");
                  t_close(fd); exit(3);
             }
             t_free(bind);

             /* listen for incomming connection */
             if ((call = (struct t_call *)t_alloc(fd, T_CALL,
                       T_ALL)) == NULL) {
                  t_error("t_alloc of t_call struct failed");
                  t_close(fd); exit(3);
             }
             if (verbose) printf("posting a listen\n");
             if (t_listen(fd, call) < 0) {
                  t_error("t_listen failed for listen_fd");
                  t_close(fd); exit(6);
             }
             if (verbose) {
                  remaddr = (tsap_address *)call->addr.buf;
                  printf("t_listen completed: from_nsap (%d)[%x][%x]... ",
                       remaddr->nsap.len, remaddr->nsap.addr[0],
                       remaddr->nsap.addr[1]);
                  printf("from_tsap (%d)[%x][%x]...\n", remaddr->tsap.len,
                       remaddr->tsap.addr[0], remaddr->tsap.addr[1]);
             }

             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 (verbose) printf("t_accept success\n");
             t_free(call);




  4                                              Intergraph Corporation - 2/94






  cox(7)                              CLIX                              cox(7)



             for (i = 0; ; i++) {
                  int total = 0;

        rcv_again:
                  if ((nbytes = t_rcv(fd, &rdata_buf[total], bufsize-total,
                                      &flags)) < 0) {
                       printf("loop #%d: ", i);
                       if (t_errno == TLOOK) {
                            printf("t_rcv failed, t_look = %d\n",
                           t_look(fd));
                            t_close(fd); exit(6);
                       }
                       t_error("t_rcv failed for fd");
                       t_close(fd); exit(8);
                  }

                  if (strncmp(rdata_buf, "END OF TEST", 11) == 0)
                       break;

                  total += nbytes;
                  if (total != bufsize) {
                       if (flags & T_MORE) {
                            if (verbose) printf(".");
                                 goto rcv_again;
                       }
                       printf("loop #%d: rcvd %d bytes instead of %d\n",
                               i, nbytes, bufsize);
                       continue;
                  } else if (verbose)
                       printf("received %d bytes, SUCCESS\n", total);

                  if ((nbytes = t_snd(fd, rdata_buf, bufsize, 0)) < 0) {
                       printf("loop #%d: ", i);
                       t_error("t_snd failed for fd");
                       t_close(fd); exit(5);
                  }

                  if (nbytes != bufsize) {
                       printf("loop #%d: ", i);
                       printf("sent %d bytes instead of %d\n");
                       continue;
                  }
             }

             /*
              * Send a finish response packet
              */
             if ((nbytes = t_snd(fd, "END OF TEST", 11, 0)) != 11) {
                  printf("Unable to send a fin response\n");
                  t_error("t_snd failed for fd");
                  exit(6);



  2/94 - Intergraph Corporation                                              5






  cox(7)                              CLIX                              cox(7)



             }

             for (;;) {
                  switch(t_look(fd)) {
                  case 0: /* No event */
                       sleep(1);
                       continue;
                  case T_DISCONNECT: {
                       struct t_discon *discon;

                       discon = (struct t_discon *)
                                 t_alloc(fd, T_DIS, T_ALL);
                       if (t_rcvdis(fd, discon) < 0)  {
                            t_error("t_rcvdis failed on cox_fd");
                            break;
                       }
                       printf("Remote disconnect reason %d\n",
                              discon->reason);
                       t_free(discon);
                       t_close(fd); exit(0);
                  }
                  default:
                       printf("unexpected event\n");
                  }
             }
             t_close(fd);
        }


    2.  The following is an example of a client program:

        #include <stdio.h>
        #include <tiuser.h>
        #include <fcntl.h>
        #include <stropts.h>

        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;

        typedef struct  {
             tsap_selector   tsap;   /* Transport SAP ID */
             nsap_address    nsap;   /* Network SAP address */
        } tsap_address;




  6                                              Intergraph Corporation - 2/94






  cox(7)                              CLIX                              cox(7)



        tsap_address remaddr;

        #define verbose  1       /* 1 on 0 off */
        #define nloop    10
        #define bufsize  1024
        #define MAXBUFSZ 4*1024

        extern int t_errno;
        char data_buf[MAXBUFSZ];
        char rdata_buf[MAXBUFSZ];

        main()
        {
             int fd, nbytes, i, j, flags, tbytes, reason;
             struct t_call *call;
             struct t_bind *bind;
             tsap_selector *loctsap;

             if ((fd = t_open("/dev/cox", O_RDWR, NULL)) < 0) {
                  t_error("/dev/cox t_open failed");
                  exit(1);
             }

             /* Bind local to TSAP 0008*/
             if ((bind = (struct t_bind *) t_alloc(fd, T_BIND,
                    T_ALL)) == NULL) {
                  t_error("cox t_bind failed");
                  t_close(fd); exit(2);
             }
             bind->addr.len = sizeof (tsap_selector);
             loctsap = (tsap_selector *) bind->addr.buf;
             loctsap->len = 2; loctsap->addr[0] = 0x0;
                   loctsap->addr[1] = 0x8;
             if (t_bind(fd, bind, bind) < 0) {
                  t_error("t_bind failed");
                  t_close(fd); exit(3);
             }
             t_free(bind);

             /* Remote TSAP address */
             remaddr.tsap.len = 2;
             remaddr.tsap.addr[0] = 0x00; remaddr.tsap.addr[1] = 0x09;
             remaddr.nsap.len = 7;
             remaddr.nsap.addr[0] = 0x00;
             remaddr.nsap.addr[1] = 0x10;
             remaddr.nsap.addr[2] = 0x01;
             remaddr.nsap.addr[3] = 0x00;
             remaddr.nsap.addr[4] = 0x10;
             remaddr.nsap.addr[5] = 0x00;
             remaddr.nsap.addr[6] = 0x03;




  2/94 - Intergraph Corporation                                              7






  cox(7)                              CLIX                              cox(7)



             /* 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");
                  t_close(fd); exit(3);
             }
             *((tsap_address *)call->addr.buf) = remaddr;
             call->addr.len = sizeof (tsap_address);
             if (t_connect(fd, call, NULL) < 0) {
                  if (t_errno == TLOOK) {
                       printf("t_rcv failed, t_look = %d\n", t_look(fd));
                       t_close(fd); exit(6);
                  }
                  t_error("t_connect failed");
                  t_close(fd); exit(4);
             }
             t_free(call);
             printf("t_connect success\n");

             /* Initialize the data buffer */
             for (i = 0; i < bufsize; i++) data_buf[i] = 0xEE;

             tbytes = 0;
             for (i = 0; i < nloop; i++) {
                  int total = 0;

                  if ((nbytes = t_snd(fd, data_buf, bufsize, 0)) < 0) {
                       printf("loop #%d: ", i);
                       t_error("t_snd failed for fd");
                       t_close(fd); exit(5);
                  }

                  if (nbytes != bufsize) {
                       printf("loop #%d: sent %d bytes instead of %d\n",
                               i, nbytes, bufsize);
                       continue;
                  } else {
                       tbytes += nbytes;
                       if (verbose)
                            printf("send %d bytes, SUCCESS\n", nbytes);
                  }
        rcv_again:
                  if ((nbytes = t_rcv(fd, &rdata_buf[total], bufsize-total,
                       &flags)) < 0) {
                       printf("loop #%d: ", i);
                            if (t_errno == TLOOK) {
                                 printf("t_rcv failed, t_look = %d\n",
                                         t_look(fd));
                                 t_close(fd); exit(6);
                            }
                       t_error("t_rcv failed for fd");



  8                                              Intergraph Corporation - 2/94






  cox(7)                              CLIX                              cox(7)



                       t_close(fd); exit(8);
                  }

                  tbytes += nbytes; total += nbytes;
                  if (total != bufsize) {
                       if (flags & T_MORE) {
                            if (verbose) printf(".");
                            goto rcv_again;
                       }
                       printf("loop #%d: rcvd %d bytes instead of %d\n",
                               i, total, bufsize);
                       continue;
                  }

                  for (j = 0; j < bufsize; j++) {
                       if ((unsigned char)rdata_buf[j]
                            != (unsigned char)0xEE) {
                            int b;
                            printf("loop #%d: ", i);
                            b = (int)rdata_buf[i];
                            printf("data error at byte #%d (%x)\n",
                           j, b);
                            goto endloop;
                       }
                  }
        successloop:
                  if (verbose)
                       printf("loop #%d SUCCESS\n", i);
        endloop:
             }

             /* Send a finish packet */
             if ((nbytes = t_snd(fd, "END OF TEST", 11, 0)) != 11) {
                  printf("Unable to send a fin\n");
                  t_error("t_snd failed for fd");
                  exit(6);
             }

             /* Receive fin response packet */
             if ((nbytes = t_rcv(fd, rdata_buf, 64, &flags)) < 0) {
                  if (t_errno == TLOOK) {
                       printf("failed to rcv a fin response\n",
                         t_look(fd));
                       t_close(fd); exit(6);
                  }
                  t_error("failed to rcv a fin response\n");
                  t_close(fd); exit(8);
             }
             if (strncmp(rdata_buf, "END OF TEST", 11) != 0) {
                  printf("Handshake close failed\n");
                  exit(10);



  2/94 - Intergraph Corporation                                              9






  cox(7)                              CLIX                              cox(7)



             }

             /* destroy the transport connection */
             if ((call = (struct t_call *)t_alloc(fd, T_CALL,
                    T_ALL)) == NULL) {
                  t_error("t_alloc of t_call struct failed");
                  t_close(fd); exit(3);
             }
             call->udata.len = sizeof (int);
             reason = 128; /* NORMAL Disconnect */
             call->udata.buf = (char *)&reason;
             t_snddis(fd, call);
             t_free(call);

             sleep(2);
             t_close(fd);
        }


  RELATED INFORMATION

    AT&T UNIX System V STREAMS Programmer's Guide, AT&T UNIX System V Network
    Programmer's Guide































  10                                             Intergraph Corporation - 2/94




Typewritten Software • bear@typewritten.org • Edmonds, WA 98026