t_sndudata(3xti_ipx)


t_sndudata -- send a message to specified transport user

Synopsis

#include "ipx_app.h" 

int t_sndudata( int ipxFd, struct t_unitdata *ud )

Parameters

(IN) ipxFd
Passes the file descriptor that was returned by t_open.

(IN) ud
Passes a pointer to (or address of) a t_unitdata structure. See "Remarks" for the structure's format.

Return values

0
Successful

-1
Unsuccessful
If the IPX(TM) driver cannot allocate memory, it sets t_errno to TSYSERR and errno to ENOSR. Errors can also cause t_errno to be set to one of the following values:

TOUTSTATE
The application hasn't done a t_bind. A t_bind must be done before issuing a t_sndudata.

TBADADDR
The destination address is smaller than the size of an IPX address (ipxAddr_t structure).

TACCES
The destination network was not found in the routing tables.

TNOADDR
The allocation of streams memory failed. Check whether more kernel memory buffers are needed.
Errors can also cause the error field of the t_uderr structure to be set. Refer to t_rcvuderr(3xti) and ``Programming with the X/Open Transport Interface (XTI)'' for more information on how to receive these error messages.

Remarks

The t_sndudata (send unit data) function enables transport users to send a self-contained data unit to the user at the specified protocol address. This call is supported as documented in t_sndudata(3xti).

The t_unitdata structure has the following format:

   struct t_unitdata { 
      struct netbuf addr; 
      struct netbuf opt; 
      struct netbuf udata; 
   }; 
The netbuf structure has the following format:
   struct netbuf { 
      unsigned int  maxlen; 
      unsigned int  len; 
      char          *buf; 
   }; 
The address (addr.buf field) must point to an ipxAddr_t structure, which has the following format:
   typedef struct ipxAddress { 
      unsigned char net[ 4 ]; 
      unsigned char node[ 6 ]; 
      unsigned char sock[ 2 ]; 
   } ipxAddr_t; 
The destination network address, node address, and socket number must be filled in this IPX address structure by the user program. The numbers must be in hi-lo order.

The IPX user sets the packet type of the outgoing IPX packet by passing 1 byte specifying the packet type in the options (opt) field. The IPX driver fills in the other fields in the outgoing IPX packet: checksum (see note below), length, transport control, source network address, source node address, and source socket number.


NOTE: To enable checksums on a packet, the IPX user must send 3 bytes of options in the outgoing IPX packet. This includes 1 byte specifying the packet type and 2 bytes initialized to IPX_CHECKSUM_TRIGGER. The IPX driver will see that the checksum is requested, calculate it, and insert the number into the header.

IPX does not support expedited data. All data is sent on a first-come, first-served basis.

A successful return by the t_sndudata call doesn't guarantee that the data has been sent. A successful return guarantees only that the data has been queued up to be sent. The t_sndudata call returns before the data has actually been transmitted, so the application must take care not to close the connection before the data has been transmitted.

If the socket is closed before the data has been transmitted, the data is dropped. Before closing the connection, you should verify that the endpoint has received all the data and is ready to close the connection.

For UNIX applications that communicate with an unknown machine type, the byte order of data sent requires attention.

For example, if a UNIX® application running on an 80386 CPU does a t_sndudata, the data portion of the IPX packet is sent across the wire in 80386 (lo-hi) order. This presents a problem if the receiving CPU (for example, a 68030) does not account for the lo-hi order.

If ud.udata.len equals zero (0), no packet is sent.

Examples

   #define MAX_DATA_SIZE 546 
   

ipxAddr_t remoteEndpointAddress; unsigned char ipxPacketType; unsigned char ipxData[IPX_MAX_DATA_SIZE]; struct t_unitdata ud;

/* There are three approaches to obtaining the address of the endpoint you ** wish to send to.

** 1. You can query a NetWare bindery for the server type you want.( This ** method assumes that you have established a connection to a NetWare ** server. Use the NWScanProperty function with NET_ADDRESS as the ** searchPropertyName.)

** 2. You can also create a file that maps a server name to an address.

** 3. You can use any appropriate method for discovering the endpoint's ** address.

** You must allocate an ipxAddr_t structure and initialize the fields to ** the endpoint's address before making the t_sndudata call. The following ** example code assumes that the endpoint has the following address: network ** address = 0x89415810, node address = 0x1, socket number = 0x500.*/

remoteEndpointAddress.net[0] = 0x89; remoteEndpointAddress.net[1] = 0x41; remoteEndpointAddress.net[2] = 0x58; remoteEndpointAddress.net[3] = 0x10; remoteEndpointAddress.node[0] = 0x00; remoteEndpointAddress.node[1] = 0x00; remoteEndpointAddress.node[2] = 0x00; remoteEndpointAddress.node[3] = 0x00; remoteEndpointAddress.node[4] = 0x00; remoteEndpointAddress.node[5] = 0x01; remoteEndpointAddress.sock[0] = 0x05; remoteEndpointAddress.sock[1] = 0x00;

ipxPacketType = 0;

ud.opt.len = sizeof(ipxPacketType); ud.opt.maxlen = sizeof(ipxPacketType); ud.opt.buf = (char *)&ipxPacketType;

ud.addr.len = sizeof(ipxAddr_t); ud.addr.maxlen = sizeof(ipxAddr_t); ud.addr.buf = (char *)&remoteEndpointAddress;

ud.udata.maxlen = IPX_MAX_DATA_SIZE;

/* actual number of data bytes sent */

ud.udata.len = IPX_MAX_DATA_SIZE; ud.udata.buf = (char *) ipxData;

if ( t_sndudata( ipxFd, &ud)<0) { t_error( "t_sndudata failed \n"); ... }

State

The state follows the state diagram in ``State transitions''.

References

t_bind(3xti_ipx), t_rcvudata(3xti_ipx), t_rcvuderr(3xti), t_sndudata(3xti)
30 January 1998
© 1998 The Santa Cruz Operation, Inc. All rights reserved.