## TCPware V5.7 Programmer's Guide

- Introduction
- Sequence of Operations
  - Client Operations
  - Server Operations
- Multicasting
- Other Operations
- INETDRIVER Socket Library
- INETDRIVER System Service Call Format
- INETDRIVER System Service Call Arguments
- INETDRIVER System Service Call Function Codes
- Sample Programs

Chapter 6

INETDRIVER Services

# Introduction

This chapter describes the internet device driver (INETDRIVER) services.

The INETDRIVER services provide an asynchronous I/O implementation of the UNIX socket calls within the OpenVMS Queue I/O Request (SYS$QIO and SYS$QIOW) system services. These system services allow for efficient socket operations in that Asynchronous System Trap (AST) routines can be associated with I/O requests.

The INETDRIVER services provide the Stanford Research Institute (SRI) QIO interface. The interface is an international de facto standard that provides a one-to-one mapping between the UNIX socket functions and the OpenVMS SYS$QIO system services.

INETDRIVER interfaces directly with the TCP, UDP, and IP (for raw functions) protocols in the transport layers. It does not replace the TCPDRIVER or UDPDRIVER services, but provides another way to communicate with them.

For details, see the TCPDRIVER Services and UDPDRIVER Services chapters.

INETDRIVER supports QIOs to:

• Create a stream, datagram, or raw socket

• Bind a socket to a local port or address

• Set a socket to listen mode

• Accept a connection

• Create a connection

• Send and receive data

• Perform other socket and control functions

Note! The TCPware for OpenVMS INETDRIVER supports stream, datagram, and raw sockets, but only for the AF_INET address family.

# Sequence of Operations

The INETDRIVER sequences of operations are divided into client operations and server operations. Each have distinct steps, as outlined in the following sections.

## Client Operations

The INETDRIVER client operations for a stream socket connection are as follows:

1 Assign an INET channel to the INET0: device using the SYS$ASSIGN system service. This creates a new INET device unit and assigns a channel to it.

2 Create a stream socket using the SYS$QIO[W] system service with the IO$_SOCKET function.

3 If you want to assign a particular address to an unnamed socket, use the SYS$QIO[W] IO$_BIND function. This is optional and not necessary under most circumstances.

4 Connect to a peer on the server using the SYS$QIO[W] IO$_CONNECT function. Specify the server's internet address any "well-known" port number.

5 Exchange data with the peer using the SYS$QIO[W] IO$_SEND and SYS$QIO[W] IO$_RECEIVE functions.

6 After the data exchange is complete, deassign the channel using the SYS$DASSGN system service.

Figure 6-1 shows the client operation steps.

Figure 6-1 Client Operation Steps see graphic

## Server Operations

The INETDRIVER server operations for a simple, single-thread stream socket connection are as follows:

1 Assign an INET listen channel to the INET0: device using the SYS$ASSIGN system service. This creates a new INET device unit and assigns a channel to it.

2 Create a stream socket using the SYS$QIO[W] IO$_SOCKET function.

3 Bind the socket to the server's "well-known" port number using the SYS$QIO[W] IO$_BIND function.

4 Enable listens and set up the listen queue length using the SYS$QIO[W] IO$_LISTEN function.

5 Assign an INET accept channel to the INET0: device using the SYS$ASSIGN system service again.

6 Accept incoming connect requests using the SYS$QIO[W] IO$_ACCEPT function on the accept channel, specifying the listen channel as a parameter. Then wait for the client to connect.

7 Exchange data with the client on the accept channel using the SYS$QIO[W] IO$_SEND and SYS$QIO[W] IO$_RECEIVE functions.

8 After the data exchange is complete, deassign the accept channel using the SYS$DASSGN system service. This closes the connection.

Repeat steps 5 through 8 to process additional server connections. Figure 6-2 shows the server operations steps.

Figure 6-2 Server Operation Steps see graphic

# Multicasting

INETDRIVER Services includes the following setsockopt and getsockopt definitions at the IPPROTO_IP level for multicasting support:

#define IP_MULTICAST_IF 2
#define IP_MULTICAST_TTL 3
#define IP_MULTICAST_LOOP 4
#define IP_ADD_MEMBERSHIP 5
#define IP_DROP_MEMBERSHIP 6

The IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP requests use the following structure:

struct ip_mreq {
struct in_addr imr_multiaddr; /* Multicast address of group */
struct in_addr imr_intrface; /* local IP address of interface */
};

# Other Operations

In addition to the routines associated with the sequence of operations above, INETDRIVER also includes other operations that:

• Set socket options (IO$_SETSOCKOPT)

• Get socket options (IO$_GETSOCKOPT)

• Shut down sockets (IO$_SHUTDOWN)

• Get socket names (IO$_GETSOCKNAME)

• Change the INET device characteristics (IO$_SETCHAR)

• Get the address of the remote end for a socket (IO$_GETPEERNAME)

• Change socket characteristics (IO$_IOCTL)

• Deliver an AST to the process if out-of-band data arrives (IO$_SETMODE | IO$_ATTNAST)

# INETDRIVER Socket Library

The Socket Library routines described in the Socket Library chapter make use of the TCPDRIVER and UDPDRIVER programming interface. An alternate set of socket routines is available that makes use of the INETDRIVER programming interface and allows a mix of socket routines and INETDRIVER QIO calls. This alternate set of socket routines is presently only available in the TCPWARE:SOCKLIB.OLB socket library (the routines are not part of the TCPWARE_SOCKLIB_SHR.EXE shareable run-time library). The following routines are available:

inet_socket | inet_socket_recv | inet_sendto | inet_socket_ioctl
inet_bind | inet_recv | inet_shutdown | inet_getsockname
inet_connect | inet_recvfrom | inet_socket_close | inet_getpeername
inet_listen | inet_socket_write | inet_setsockopt | inet_socket_perror
inet_accept | inet_socket_send | inet_getsockopt | inet_tcpware_server
inet_socket_read | inet_send |  |

The socket number (descriptor) used by these routines is the VMS I/O channel of the INETDRIVER device being used. This allows for the mixing of these routines and direct QIOs to the driver.

# INETDRIVER System Service Call Format

The format for the INETDRIVER SYS$QIO system service call is as follows:

status = SYS$QIO[W](efn, chan, func, iosb, astadr, astprm, p1, p2, p3, p4, p5, p6)

The TCPWARE_INCLUDE:INETIODEF.H file provides definitions for the QIO function codes.

Note! The E-prefix status codes (such as ECONNRESET) listed under the STATUS headings are returned in the I/O status block (iosb) and are not the UNIX errno values. As described in Table 6-1 under the iosb argument, the values returned for these codes are the UNIX errno values multiplied by 8 and logically ORed with 0x8000.
The TCPware Socket Library Runtime Library (RTL) contains the message pointer to the SYS$MESSAGE:TCPWARE_MSG.EXE file. The RTL also contains definitions for the status values. These are the UNIX errno names prefixed by TCPWARE$_ (for example, TCPWARE$_ECONNRESET).

Note! The vertical bar ( | ) used in some of the functions described in this chapter is the C bitwise inclusive OR operator.

# INETDRIVER System Service Call Arguments

You invoke UDPDRIVER system service calls with the standard OpenVMS QIO mechanism.

See the appropriate OpenVMS documentation (for example, the Introduction to VMS System Services volume) for details on the QIO mechanism.

The following sections describe each system call argument.

efn

OpenVMS usage: | ef_number
type: | longword (unsigned)
access: | read only
mechanism: | by value

(Optional) Number of the event flag to be set when the I/O operation completes.

chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

I/O channel assigned to the INET device to which the request is directed.

func

OpenVMS usage: | function_code
type: | word (unsigned)
access: | read only
mechanism: | by value

Device-specific function codes and modifiers for each operation.

Note! INETDRIVER System Service Call Function Codes describes each function code in detail.

iosb

OpenVMS usage: | io_status_block
type: | quadword (unsigned)
access: | write only
mechanism: | by reference

I/O status block that receives the final completion status of the I/O operation, structured as in Figure 6-3.

Figure 6-3 I/O Status Block see graphic

Table 6-1 describes the status block fields in more detail.-

Table 6-1 I/O Status Block Fields (Continued)

Field Name | Description
Transfer Byte Count | Number of bytes of data transferred in the I/O operation.
Status Code | SS$ status code or special error status code. If the low bit (0) of the OpenVMS error code is clear, the network has returned an error. If the most significant bit of this word is set (mask of 0x8000), the status code is the UNIX errno code multiplied by 8 and logically ORed with 0x8000.
Function-Specific | Varies for each device and function code.

astadr

OpenVMS usage: | ast_procedure
type: | procedure entry mask
access: | call without stack unwinding
mechanism: | by reference

Asynchronous system trap (AST) routine to be executed when the I/O is completed.

astprm

OpenVMS usage: | user_arg
type: | longword (unsigned)
access: | read only
mechanism: | by value

AST parameter to be passed to the AST routine.

p1 to p6

OpenVMS usage: | varying_arg
type: | longword (unsigned)
access: | read only or write only
mechanism: | by reference or by value

Function-specific parameters, as described for each function.

# INETDRIVER System Service Call Function Codes

System service call function codes specify what action the QIO performs.

IO$_ACCEPT

Waits for a connection to a listening socket and associates a OpenVMS channel to the socket for that new connection. The connection's socket has the same properties as the listening socket.

If no pending connections exist on the queue and the socket is not marked as nonblocking, IO$_ACCEPT blocks the caller until a connection is made to the listening socket. If the socket is marked as nonblocking and no pending connections exist on the queue, IO$_ACCEPT returns an EWOULDBLOCK error.

Multiple IO$_ACCEPT requests are supported on a single channel.

See IO$_ACCEPT_WAIT for an alternative to IO$_ACCEPT.

Format

status = SYS$QIO(efn, new-inet-chan, IO$_ACCEPT, iosb, astadr, astprm, address, addrlen, inet-chan, 0, 0, 0)

Arguments

chan=new-inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

OpenVMS channel to a newly-created INET: device. This channel should be created by using SYS$ASSIGN to assign a new channel to INET0: prior to issuing the IO$_ACCEPT function. The accepted connection uses this channel.

p1=address

OpenVMS usage: | special_structure
type: | structure defined below
access: | write only
mechanism: | by reference

Optional pointer to a structure that receives the peer's address for the connection following completion of the IO$_ACCEPT function. The structure is defined as follows:

struct {
unsigned long Length;
struct sockaddr_in Address;
}

p2=addrlen

OpenVMS usage: | word_unsigned
type: | word (unsigned)
access: | read only
mechanism: | by value

Length (in bytes) of the buffer to which the address argument points. The value must be at least 20 bytes.

p3=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

OpenVMS channel for the INET: device on which the IO$_LISTEN was performed. After accepting the connection, this device remains available to accept additional connections.

Status

EALREADY | Operation is already in progress or the socket is in use (e.g. an IO$_ACCEPT is active on the channel).
ECONNABORTED | Listening channel was shut down or aborted.
EINVAL | Operation is not valid (for a nonstream socket), or an invalid inet-chan or addrlen argument was specified.
ENETDOWN | Network was shut down.
ENOTSOCK | No socket exists on the listening channel.
EOPNOTSUPP | Socket is not of type SOCK_STREAM.
EWOULDBLOCK | Connection is marked as nonblocking and no connection is waiting to be accepted.
SS$_IVCHAN | Invalid listening channel number was specified.
SS$_THIRDPARTY | Network is being shut down.

IO$_ACCEPT_WAIT

Waits for an incoming connection on a listening socket without accepting the connection. When the IO$_ACCEPT_WAIT is complete, a connection is available for accepting; IO$_ACCEPT is then used to accept it.

Multiple IO$_ACCEPT_WAIT requests are supported on a single channel.

IO$_ACCEPT_WAIT is useful to avoid holding an additional INET channel while waiting to service a connection.

Format

status = SYS$QIO(efn, inet-chan, IO$_ACCEPT_WAIT, iosb, astadr, astprm, 0, 0, 0, 0, 0, 0)

Argument

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

OpenVMS channel to the INET: device on which the IO$_LISTEN was performed.

Status

ECONNABORTED | Listening channel was shut down or aborted.
EINVAL | Operation is not valid (for a nonstream socket), or an invalid inet-chan or addrlen argument was specified.
ENETDOWN | Network was shut down.
ENOTSOCK | No socket exists on the listening channel.
EOPNOTSUPP | Socket is not of type SOCK_STREAM.
EWOULDBLOCK | Connection is marked as nonblocking and no connection can be accepted.
SS$_THIRDPARTY | Network is being shut down.

IO$_BIND

Assigns an address to an unbound socket. When a socket is created with IO$_SOCKET, it has no assigned address. IO$_BIND requests that the address be assigned to the socket.

Normally used by servers to bind to their "well-known" port number before issuing the IO$_LISTEN function. Clients typically do not use this function, since IO$_CONNECT normally will assign an unused port number.

Note! To bind to port numbers 1 through 1023, a process must be running under a privileged UIC, or with the SYSPRV or BYPASS privilege.

Format

status = SYS$QIO(efn, inet-chan, IO$_BIND, iosb, astadr, astprm, name, namelen, 0, 0, 0, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

OpenVMS channel to the INET: device on which the IO$_SOCKET was performed.

p1=name

OpenVMS usage: | socket_address
type: | structure sockaddr_in
access: | read only
mechanism: | by reference

Address to which the socket should be bound.

p2=namelen

OpenVMS usage: | socket_address_length
type: | longword (unsigned)
access: | read only
mechanism: | by value

Length of the name argument (in bytes).

Status

EACCES | Specified address is not available from the local machine.
EADDRNOTAVAIL | Requested address is protected; the user has no permission to have access to it.
EADDRINUSE | Specified address is already in use.
EINVAL | Operation is not valid (for a nonstream socket).
ENETDOWN | Network was shut down.
SS$_THIRDPARTY | Network is being shut down.

IO$_CONNECT

For stream sockets, attempts a connection to a peer socket. For datagram sockets, permanently specifies the peer to which the datagrams are to be sent or from which they are to be received.

Format

status = SYS$QIO(efn, inet-chan, IO$_CONNECT, iosb, astadr, astprm, name, namelen, 0, 0, 0, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Channel to the socket.

p1=name

OpenVMS usage: | socket_address
type: | structure sockaddr_in
access: | read only
mechanism: | by reference

Address of the peer to which the socket should be bound.

p2=namelen

OpenVMS usage: | socket_address_length
type: | longword (unsigned)
access: | read only
mechanism: | by value

Length of the name argument (in bytes).

Status

EADDRNOTAVAIL | Requested address is protected; the user has no permission to have access to it.
EADDRINUSE | Specified address is already in use.
EALREADY | Operation is already in progress.
ECONNABORTED | Operation was aborted.
ECONNREFUSED | Connection was refused by the peer.
EHOSTUNREACH | Host was unreachable.
EINVAL | Socket has already been used for a connection, or the namelen argument is invalid.
EISCONN | Socket is already connected.
ENETDOWN | Network has been shut down.
ENETUNREACH | Destination network is unreachable.
EOPNOTSUPP | Operation is not supported (e.g., a connect on a listening socket).
ETIMEDOUT | Connection timed out.
EWOULDBLOCK | Socket is marked as nonblocking; connection attempt is in progress.
SS$_THIRDPARTY | Network is being shut down.

IO$_GETPEERNAME

Returns the address of the peer connected to the specified socket.

Format

status = SYS$QIO(efn, inet-chan, IO$_GETPEERNAME, iosb, astadr, astprm, address, addrlen, 0, 0, 0, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Channel to the socket.

p1=address

OpenVMS usage: | socket_address
type: | structure sockaddr_in
access: | write only
mechanism: | by reference

Receives the peer's address.

p2=addrlen

OpenVMS usage: | socket_address_length
type: | longword (unsigned)
access: | modify
mechanism: | by reference

On entry, contains the byte length of the space pointed to by address. On return, it contains the byte length of the data returned.

Status

EINVAL | Invalid addrlen was specified.
ENETDOWN | Network has been shut down.
ENOTCONN | Socket is not connected.
SS$_THIRDPARTY | Network is being shut down.

IO$_GETSOCKNAME

Returns the local address of a socket.

Format

status = SYS$QIO(efn, inet-chan, IO$_GETSOCKNAME, iosb, astadr, astprm, address, addrlen, 0, 0, 0, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Channel to the socket.

p1=address

OpenVMS usage: | socket_address
type: | structure sockaddr_in
access: | write only
mechanism: | by reference

Receives the local or multicast address.

p2=addrlen

OpenVMS usage: | socket_address_length
type: | longword (unsigned)
access: | modify
mechanism: | by reference

On entry, contains the byte length of the space pointed to by address. On return, it contains the byte length of the data returned.

Status

EINVAL | addrlen argument is invalid.
ENETDOWN | Network was shut down.
SS$_THIRDPARTY | Network is being shut down.

IO$_GETSOCKOPT

Retrieves the value of options associated with a socket.

The TCPWARE_INCLUDE:SOCKET.H file contains definitions for the socket-level options. The IPPROTO_IP level options defined in the TCPWARE_INCLUDE:IN.H file are not compatible with INETDRIVER.

Format

status = SYS$QIO(efn, inet-chan, IO$_GETSOCKOPT, iosb, astadr, astprm, level, optname, optval, optlen, 0, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Channel to the socket.

p1=level

OpenVMS usage: | option_level
type: | longword (unsigned)
access: | read only
mechanism: | by value

SOL_SOCKET to change socket options, or IPPROTO_IP to change IP options (which requires system UIC, SYSPRV, or BYPASS privilege).

p2=optname

OpenVMS usage: | option_name
type: | longword (unsigned)
access: | read only
mechanism: | by value

TCPware ignores this option where indicated. However, you should include it if you created other routines that set this option to that you do not get an error message.

See Table 6-4 and Table 6-6 for the allowable values.

p3=optval

OpenVMS usage: | (dependent on optname)
type: | byte buffer
access: | write only
mechanism: | by reference

Pointer to a buffer that is to receive the current value of the option. The format of this buffer is dependent on the option requested. Options other than SO_LINGER return a longword value. For those options that are enabled or disabled, 0 is returned if disabled, 1 is returned if enabled.

SO_LINGER uses the following structure for the linger value:

structlinger {
intl_onoff ;/* option on/off */
intl_linger ;/* linger time */
};

p4=optlen

OpenVMS usage: | option_length
type: | longword (unsigned)
access: | modify
mechanism: | by reference

On entry, contains the byte length of the space pointed to by optval. On return, contains the byte length of the option returned.

Status

EINVAL | level specified is invalid.
ENOPROTOOPT | Option is unknown.
ENETDOWN | Network was shut down.
SS$_THIRDPARTY | Network is being shut down.

IO$_IOCTL

Manipulates socket characteristics. The TCPWARE_INCLUDE:IOCTL.H file contains definitions for the IO$_IOCTL request codes.

Note! This function does not support operations to set network interface information.

Format

status = SYS$QIO(efn, inet-chan, IO$_IOCTL, iosb, astadr, astprm, request, argp, 0, 0, 0, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Channel to the socket.

p1=request

OpenVMS usage: | ioctl_request
type: | longword (unsigned)
access: | read only
mechanism: | by value

IO$_IOCTL function to perform. The IO$_IOCTL functions are listed in Table 6-2.

p2=argp

OpenVMS usage: | arbitrary
type: | byte buffer
access: | read, write, or modify, depending on request
mechanism: | by reference

Pointer to a buffer whose format and function depends on the request specified.

Table 6-2 Request Argument Values (Continued)

Value | Description
FIONBIO | Sets/clears nonblocking mode
FIONREAD | Returns bytes available for reading
SIOCADDRT | Adds a routing entry
SIOCATMARK | Returns whether the read point is at the out-of-band (TCP urgent) mark
SIOCDARP | Deletes an address resolution (ARP) entry
SIOCDELRT | Deletes a routing entry
SIOCGARP | Gets an address resolution (ARP) entry
SIOCGIFCONF | Returns list of network interfaces
SIOCGIFADDR | Returns the internet address for an interface
SIOCGIFBRDADDR | Returns the broadcast address for an interface
SIOCGIFDSTADDR | Returns the destination address for a point-to-point interface
SIOCGIFFLAGS | Returns the flags for an interface
SIOCGIFMETRIC | Returns the metric for an interface
SIOCGIFMTU | Returns the minimum transmission unit for an interface
SIOCGIFNETMASK | Returns the network mask for an interface
SIOCSARP | Adds an address resolution (ARP) entry

Status

ENOPROTOOPT | request specified is invalid.
ENETDOWN | Network was shut down.
SS$_THIRDPARTY | Network is being shut down.

IO$_LISTEN

Places the stream in a listen state and specifies the maximum number of incoming connections that can be queued waiting to be accepted. This backlog must be specified before accepting a connection on a socket.

Applies to sockets of type SOCK_STREAM only.

Format

status = SYS$QIO(efn, inet-chan, IO$_LISTEN, iosb, astadr, astprm, backlog, 0, 0, 0, 0, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Channel to the socket.

p1=backlog

OpenVMS usage: | connection_backlog
type: | longword (unsigned)
access: | read only
mechanism: | by value

Maximum length of the queue of pending connections. If a connection request arrives when the queue is full, the request is ignored. The backlog queue is limited by the TCPware BACKLOG_LIMIT parameter. If the specified value is greater than BACKLOG_LIMIT, BACKLOG_LIMIT is used.

See the ADD SERVICE command description in Chapter 2, NETCU Commands, in the NETCU Command Reference for details on setting the BACKLOG_LIMIT parameter.

Status

EISCONN | Socket is already connected.
EOPNOTSUPP | Operation is not supported (such as when the connection on a listening socket).
ENETDOWN | Network was shut down.
SS$_THIRDPARTY | Network is being shut down.

IO$_RECEIVE

Receives data from a socket.

The length of the data received is returned in the second word of the I/O Status Block (iosb). A count of 0 indicates an end-of-file condition, or the connection was closed.

For SOCK_DGRAM and SOCK_RAW messages, if the message is too long to fit in the supplied buffer, excess bytes are discarded. For SOCK_STREAM data, no bytes are discarded, even though the amount of data processed on a request may be different than the amount sent.

If no data is available for the socket, the IO$_RECEIVE function waits for data to arrive, unless the socket is in nonblocking mode.

Format

status = SYS$QIO(efn, inet-chan, IO$_RECEIVE, iosb, astadr, astprm, buffer, size, flags, from, fromlen, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Channel to the socket.

p1=buffer

OpenVMS usage: | arbitrary
type: | write buffer
access: | write only
mechanism: | by reference

Address of the user's buffer.

p2=size

OpenVMS usage: | longword_unsigned
type: | longword (unsigned)
access: | read only
mechanism: | by value

Byte size of the user's buffer. The value should not be greater than 64000 bytes. The actual number of bytes read is returned in the iosb.

p3=flags

OpenVMS usage: | mask_longword
type: | longword (unsigned)
access: | read only
mechanism: | by value

Control information that affects the IO$_RECEIVE function and is formed by logically OR-ing one or more of the following values:

#define MSG_OOB 0x1/*send out-of-band data*/
#define MSG_PEEK 0x2*peek at incoming message*/
#define MSG_NONBLOCKING 0x10/*override blocking state*/
#define MSG_TIME 0x100/*limit receive wait time*/

The MSG_OOB flag causes IO$_RECEIVE to read any out-of-band data arriving on the socket.

The MSG_PEEK flag causes IO$_RECEIVE to read the data present in the socket without removing the data. This allows the caller to view the data, but leave it in the socket for future IO$_RECEIVE functions.

The MSG_NONBLOCKING flag causes IO$_RECEIVE to be a nonblocking request. An EWOULDBLOCK status would be returned if the request cannot be completed immediately.

The MSG_TIME flag (for datagram sockets only) causes IO$_RECEIVE to complete within SO_RCVTIMEO seconds with the ETIMEDOUT status (if no message is received). Use the IO$_SETSOCKET function to set SO_RCVTIMEO.

p4=from

OpenVMS usage: | special_structure
type: | structure defined below
access: | write only
mechanism: | by reference

For SOCK_DGRAM and SOCK_RAW sockets, the optional from argument is a pointer to a structure that contains the address of the socket that sent the packet following completion of the IO$_RECEIVE function. The structure is defined as follows:

struct {
unsigned short Length;
struct sockaddr_inAddress;
} ;

Note! The from argument is ignored for SOCK_STREAM sockets.

p5=fromlen

OpenVMS usage: | word_unsigned
type: | word (unsigned)
access: | read only
mechanism: | by value

For SOCK_DGRAM sockets, byte length (at least 18 bytes) of the buffer pointed to by the from argument.

Note! The fromlen argument is ignored for SOCK_STREAM sockets.

Status

ECONNRESET | Connection was reset by the peer.
EHOSTUNREACH | Host was unreachable.
EINVAL | from argument is invalid, or no out-of-band data was available.
ENETDOWN | Network was shut down.
ENOTCONN | Socket is not connected.
EOPNOTSUPP | Out-of-band request exists on a nonstream socket.
ETIMEDOUT | Connection timed out.
EWOULDBLOCK | Request would block.
SS$_CANCEL | Request was cancelled.
SS$_THIRDPARTY | Network is being shut down.

IO$_SEND

Sends stream data (for stream sockets), messages (for datagram sockets), or raw data to a socket.

IO$_SEND blocks if no buffer space is available at the socket to hold the data to be transmitted, unless the socket was placed in nonblocking mode. For datagram sockets, if the message is too long to pass through the underlying protocol in a single unit, an EMSGSIZE status is returned and the message is not transmitted.

Format

status = SYS$QIO(efn, inet-chan, IO$_SEND, iosb, astadr, astprm, buffer, size, flags, to, tolen, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Channel to the socket.

p1=buffer

OpenVMS usage: | arbitrary
type: | write buffer
access: | read only
mechanism: | by reference

Address of the user's buffer.

p2=size

OpenVMS usage: | longword_unsigned
type: | longword (unsigned)
access: | read only
mechanism: | by value

Byte size of the user's buffer. The actual number of bytes sent is returned in the iosb. The value should not be greater than 64000 bytes.

p3=flags

OpenVMS usage: | mask_longword
type: | longword (unsigned)
access: | read only
mechanism: | by value

Control information that affects the IO$_SEND function and is formed by logically ORing one or more of the following values:

#define MSG_OOB 0x1/*send out-of-band data*/
#define MSG_NONBLOCKING 0x10/*override blocking state*/

The MSG_OOB flag causes IO$_SEND to send out-of-band data on sockets that support this operation (e.g., SOCK_STREAM sockets).

The MSG_NONBLOCKING flag causes IO$_SEND to be a nonblocking request. An EWOULDBLOCK status would be returned if the request cannot be completed immediately.

Note! For stream sockets, some of the data may have been sent: the amount is returned in the second word of the iosb.

p4=to

OpenVMS usage: | socket_address
type: | struct socket address
access: | read only
mechanism: | by reference

For datagram sockets, the optional to argument is a pointer to the address to which the packet should be transmitted.

p5=tolen

OpenVMS usage: | socket_address_length
type: | longword (unsigned)
access: | read only
mechanism: | by value

For datagram sockets, the optional tolen argument contains the byte length of the address pointed to by the to argument.

Note! The to and tolen arguments are ignored for SOCK_STREAM sockets.

Status

ECONNRESET | Connection was reset by the peer.
EDESTADDRREQ | Destination address was not specified.
EHOSTUNREACH | Host was unreachable.
EINVAL | to argument is invalid, or no out-of-band data was available.
EISCONN | Socket is already connected.
EMSGSIZE | Datagram was too large.
ENETDOWN | Network was shut down.
ENETUNREACH | Destination network is unreachable.
ENOTCONN | Socket is not connected.
EOPNOTSUPP | Out-of-band request exists on a nonstream socket.
EPIPE | Connection was broken.
ETIMEDOUT | Connection timed out.
EWOULDBLOCK | Request would block.
SS$_THIRDPARTY | Network is being shut down.

IO$_SETCHAR

Sets special device characteristics for the INET device rather than for the socket attached to it. These operations are normally used by the TCPware master server (NETCP) process only.

Note! IO$_SETCHAR requires LOG_IO privileges.

Format

status = SYS$QIO(efn, inet-chan, IO$_SETCHAR, iosb, astadr, astprm, flags, 0, 0, 0, 0, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Channel to the socket.

p1=flags

OpenVMS usage: | mask_longword
type: | longword (unsigned)
access: | read only
mechanism: | by reference

Address of a longword bit mask of one or more of the values that appear in Table 6-3. If IO$_SETCHAR is not called, all options are set to OFF.

Table 6-3 Flags Argument Values (Continued)

Bit | Description
0 | If set, makes the device permanent. If clear, makes the device temporary (default).
1 | If set, makes the device shareable. If clear, makes the device nonshareable (default).
2 | If set, allow the device to be handed off. (The device is not deleted when the last channel is deassigned, but is deleted the next time the last channel is deassigned.)

Status

SS$_NOPRIV | Argument requires LOG_IO privileges.

IO$_SETMODE | IO$M_ATTNAST

Enables an AST to be delivered to the process when out-of-band (TCP urgent) data is received on the socket. This function is similar to the UNIX 4.3BSD SIGURG signal being delivered.

This is a once-only AST. After the AST is delivered, you must explicitly re-enable it using this function if you want the AST to be delivered when future out-of-band data is received.

Format

status = SYS$QIO(efn, inet-chan, IO$_SETMODE | IO$M_ATTNAST, iosb, astadr, astprm, routine, parameter, acmode, 0, 0, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Channel to the socket.

p1=routine

OpenVMS usage: | ast_procedure
type: | procedure entry mask
access: | call without stack unwinding
mechanism: | by reference

Address of the AST routine to call when out-of-band data arrives on the socket. To cancel AST delivery, specify routine as 0.

p2=parameter

OpenVMS usage: | user_arg
type: | longword (unsigned)
access: | read only
mechanism: | by value

Argument to call the AST routine.

p3=acmode

OpenVMS usage: | access_mode
type: | longword (unsigned)
access: | read only
mechanism: | by value

Access mode for the AST.

IO$_SETSOCKOPT

Manipulates options associated with a socket.

The TCPWARE_INCLUDE:SOCKET.H file contains definitions for the socket-level options. The IPPROTO_IP level options defined in the TCPWARE_INCLUDE:IN.H file are not compatible with INETDRIVER.

Format

status = SYS$QIO(efn, inet-chan, IO$_SETSOCKOPT, iosb, astadr, astprm, level, optname, optval, optlen, 0, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Channel to the socket.

p1=level

OpenVMS usage: | option_level
type: | longword (unsigned)
access: | read only
mechanism: | by value

SOL_SOCKET to change socket options, IPPROTO_TCP to change TCP options, or IPPROTO_IP to change IP options (which requires a SYSTEM UIC, or the SYSPRV or BYPASS privilege).

p2=optname

OpenVMS usage: | option_name
type: | longword (unsigned)
access: | read only
mechanism: | by value

Option to be manipulated. See Table 6-4 and Table 6-6.

p3=optval

OpenVMS usage: | (dependent on optname)
type: | byte buffer
access: | read only
mechanism: | by reference

Pointer to a buffer that contains the value to which the option is to be set. The format of this buffer is dependent on the option requested.

p4=optlen

OpenVMS usage: | option_length
type: | longword (unsigned)
access: | read only
mechanism: | by reference

Byte length of the optval buffer

Table 6-4 Optname Argument Values for SOL_SOCKET Level (Continued)

SOL_SOCKET Option | Description
SO_BROADCAST | Enables or disables broadcasting on the socket (ignored)
SO_DEBUG | Enables debugging in the protocol modules (ignored)
SO_DONTROUTE | Prevents routing applied to outgoing messages (ignored)
SO_ERROR | Returns current socket error (if any)
SO_KEEPALIVE | Keeps connections alive
SO_LINGER | Delay (in seconds) before closing a socket (ignored)
SO_OOBINLINE | Leaves received out-of-band data in line
SO_REUSEADDR | Allows local address reuse
SO_RCVBUF | Size of the internal receive buffer
SO_RCVLOWAT | (Ignored)
SO_RCVTIMEO | Receive timeout time (ignored for stream sockets)
SO_SNDBUF | Size of the internal send buffer
SO_SNDLOWAT | (Ignored)
SO_SNDTIMEO | Send timeout time (ignored for datagram sockets)
SO_TYPE | Type of socket (stream or datagram)
SO_USELOOPBACK | Bypasses hardware when possible (ignored)

Table 6-5 Optname Argument Values for IPPROTO_TCP Level (Continued)

IPPROTO_TCP Option | Description
TCP_KEEPALIVE | Determines how long an idle socket should remain open

Table 6-6 Optname Argument Values for IPPROTO_IP Level (Continued)

IPPROTO_IP Option | Description
IP_OPTIONS (1) | Gets or sets IP options to be sent in subsequent datagrams
IP_MULTICAST_IF (2) | Gets or sets the interface used for sending multicast datagrams
IP_MULTICAST_TTL (3) | Gets or sets the IP time-to-live (TTL) to sent in subsequent datagrams
IP_MULTICAST_LOOP (4) | Gets or sets whether sent multicast datagrams should be looped back locally
IP_ADD_MEMBERSHIP (5) | Adds a multicast group membership for an interface
IP_DROP_MEMBERSHIP (6) | Drops a multicast group membership from an interface

Status

EADDRNOTAVAIL | Address not available for use.
EADDRINUSE | Address already in use.
EINVAL | level specified is invalid.
ENETDOWN | Network was shut down.
ENOBUFS | Insufficient memory for requests.
ENOPROTOOPT | Option is unknown.
ETOOMANYREFS | Too many multicast memberships requested.
SS$_THIRDPARTY | Network is being shut down.

IO$_SHUTDOWN

Causes all or part of a full-duplex connection on a socket to be shut down. Can be used to signal an end-of-file to the peer without closing the socket itself, which would also prevent further data from being received.

Format

status = SYS$QIO(efn, inet-chan, IO$_SHUTDOWN, iosb, astadr, astprm, how, 0, 0, 0, 0, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Channel to the socket.

p1=how

OpenVMS usage: | longword_unsigned
type: | longword (unsigned)
access: | read only
mechanism: | by value

Part of the full-duplex connection to shut down, as shown in Table 6-7.

Table 6-7 How Argument Values (Continued)

Value | Description
0 | Further receive operations are not allowed
1 | Further send operations are not allowed
2 | Further receive and send operations are not allowed

Status

EINVAL | how specified is invalid.
ENETDOWN | Network was shut down.
SS$_THIRDPARTY | Network is being shut down.

IO$_SOCKET

Creates the desired socket type. The three currently supported types are stream sockets (SOCK_STREAM), datagram sockets (SOCK_DGRAM), and raw sockets (SOCK_RAW).

Note! Before issuing the IO$_SOCKET function, an INET channel must first be assigned to the INET0: device, using SYS$ASSIGN.

Format

status = SYS$QIO(efn, inet-chan, IO$_SOCKET, iosb, astadr, astprm, AF_INET(2), type, protocol, 0, 0, 0)

Arguments

chan=inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Channel to the socket.

p1=addressfam=AF_INET (2)

OpenVMS usage: | address_family
type: | longword (unsigned)
access: | read only
mechanism: | by value

Must be AF_INET (2).

p2=type

OpenVMS usage: | socket_type
type: | longword (unsigned)
access: | read only
mechanism: | by value

Semantics of communication using the created socket. The three currently supported types are: SOCK_STREAM (for a TCP socket), SOCK_DGRAM (for a UDP socket), and SOCK_RAW (for a raw socket).

p3=protocol

OpenVMS usage: | protocol_number
type: | longword (unsigned)
access: | read only
mechanism: | by value

For TCP and UDP sockets, the protocol argument value must be 0. For raw sockets, a non-zero protocol can be specified.

Status

ENETDOWN | Network was shut down.
EPROTONOSUPPORT | Requested addressfam, type, or protocol is not supported.
SS$_THIRDPARTY | Network is being shut down.

SYS$ASSIGN

Assigns a channel to a device.

Format

status = SYS$ASSIGN (devnam, inet-chan, [acmode], [mbxnam])

Arguments

devnam

OpenVMS usage: | device_name
type: | character coded text string
access: | read only
mechanism: | by descriptor fixed length string descriptor

Address of a character string descriptor pointing to the device name string.

inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | write only
mechanism: | by reference

Address of a word into which SYS$ASSIGN writes the channel number.

acmode

OpenVMS usage: | access_mode
type: | longword (unsigned)
access: | read only
mechanism: | by value

Optional access mode associated with the channel. The most privileged access mode used is that of the caller.

mbxnam

OpenVMS usage: | device_name
type: | character coded text string
access: | read only
mechanism: | by descriptorfixed length string descriptor

Optional logical mailbox associated with the device. (Not supported by INETDRIVER.)

Status

See HP’s VMS System Services Reference Manual for a complete list of status messages.

SYS$CANCEL

Cancels any I/O that is pending on a socket.

The I/O will be completed with an iosb status of SS$CANCEL.

Outstanding I/O operations are automatically cancelled at image exit.

Format

status = SYS$CANCEL (inet-chan)

Argument

inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Number of the channel to be cancelled.

Status

See HP’s VMS System Services Reference Manual for a complete list of status messages.

SYS$DASSGN

Closes a socket.

When you deassign a channel, any outstanding I/O is completed with an iosb status of SS$CANCEL.

I/O channels are automatically deassigned at image exit.

Format

status = SYS$DASSGN (inet-chan)

Argument

inet-chan

OpenVMS usage: | channel
type: | word (unsigned)
access: | read only
mechanism: | by value

Number of the channel to be deassigned.

Status

See HP’s VMS System Services Reference Manual for a complete list of status messages.

# Sample Programs

The following pair of sample programs, which show the use of stream sockets with SYS$QIO system service calls to the INETDRIVER, are included in the TCPWARE_COMMON:[TCPWARE.EXAMPLES] directory:

• INETDRIVER_CLIENT.C

• INETDRIVER_SERVER.C

They are functionally the same as the TCP_SOCKET_CLIENT.C and TCP_SOCKET_SERVER.C sample programs.

The client calling sequence is as follows:

1 Assign a channel for the connection ($ASSIGN)

2 Create a stream socket (IO$_SOCKET)

3 Connect to the server (IO$_CONNECT)

4 Exchange data (IO$_SEND, IO$_RECEIVE)

5 Close the connection ($DASSGN)

The server calling sequence is as follows:

1 Assign a channel to listen on ($ASSIGN)

2 Create a stream socket to listen on (IO$_SOCKET)

3 Bind the socket to an address (IO$_BIND)

4 Listen for incoming connections (IO$_LISTEN)

5 Assign a channel to accept on ($ASSIGN)

6 Accept the incoming connection (IO$_ACCEPT)

7 Exchange data (IO$_SEND, IO$_RECEIVE)

8 Close the connection ($DASSGN)

To build any one of these applications using DEC C, enter:

$ CC/DECC/PREFIX=ALL filename
$ LINK filename

Ctrl/Z

To build any one of these applications using VAX C, enter:

$ CC/VAXC filename
$ LINK filename, TCPWARE:UCX$IPC/LIB, SYS$INPUT/OPTIONS-
_$ SYS$SHARE:VAXCRTL/SHARE

Ctrl/Z