hp.com home products and services support and drivers solutions how to buy
cd-rom home
End of Jump to page title
HP OpenVMS systems
documentation

Jump to content


HP TCP/IP Services for OpenVMS

HP TCP/IP Services for OpenVMS
Sockets API and System Services Programming


Previous Contents Index

  1. The $QIO(IO$_ACCESS|IO$M_ACCEPT) function establishes the connection with the client.
  2. The IO$WRITEVBLK function specifies the address of the return buffer in p1, and the length of the return buffer in p2.
  3. You can also specify a list of write buffers by omitting the p1 and p2 parameters and instead passing the list of buffers as the p5 parameter.
  4. When writing a list of buffers, the p5 parameter is used; when reading a list, the p6 parameter is used. For information about specifying input parameter lists, see Section 5.5.1.

2.14 Writing OOB Data (TCP Protocol)

If your application uses TCP, you can send out-of-band (OOB) data to a remote process. At the remote process, the message is delivered to the user through either the data receive or the OBB data receive mechanism. You can write only 1 byte of OOB data at a time.

2.14.1 Writing OOB Data (Sockets API)

To send OOB data to a remote process, use the MSG_OOB flag with the send() , sendmsg() , and sendto() functions.

Example 2-22 shows a TCP server using the MSG_OOB flag with the send() routine.

Example 2-22 Writing OOB Data (Sockets API)

/* This program accepts a connection on TCP port 1234, sends the string, 
   "Hello, world!", waits two seconds, sends an urgent BEL (^G), waits 
   another two seconds, repeats the Hello message, and terminates. */ 
 
#include <types.h> 
#include <in.h> 
#include <socket.h> 
#include <unixio.h> 
 
#define PORTNUM 123 
main() { 
   struct sockaddr_in lcladdr; 
   int r, s, one = 1; 
   char *message = "Hello, world!\r\n", 
        *oob_message = "\007"; 
   memset() 
   
   lcladdr.sin_family = AF_INET; 
   lcladdr.sin_addr.s_addr = INADDR_ANY; 
   lcladdr.sin_port = htons(PORTNUM); 
   if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) perror("socket"); 
   if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) 
      perror("setsockopt"); 
   if (bind(s, &lcladdr, sizeof(lcladdr))) perror("bind"); 
   if (listen(s, 1)) perror("listen"); 
   if ((r = accept(s, 0, 0)) < 0) perror("accept"); 
   if (send(r, message, strlen(message), 0) != strlen(message)) 
      perror("send"); 
   sleep(2); 
   if (send(r,(1) oob_message,(2) strlen(oob_message),(3) MSG_OOB (4)) != 
              strlen(oob_message)) perror("send"); 
   sleep(2); 
   if (send(r, message, strlen(message), 0) != strlen(message)) 
      perror("send"); 
   sleep(2); 
   if (close(r)) perror("close"); 
   if (close(s)) perror("close"); 
} 

The send() routine is used to send OOB data to a remote socket, as follows:

  1. r specifies the remote socket descriptor connected to the local socket as a result of a call to the socket() routine.
  2. oob_message is the buffer containing the OOB data.
  3. strlen(oob_message) specifies the length, in bytes, of the buffer containing the out-of-band data.
  4. MSG_OOB is the flag that indicates the data will be sent out of band.

2.14.2 Writing OOB Data (System Services)

To send out-of-band data to a remote process, use the IO$_WRITEVBLK function with the IO$M_INTERRUPT modifier. Example 2-23 shows a TCP server using the TCPIP$C_MSG_OOB flag.

Example 2-23 Writing OOB Data (System Services)

/* 
** 
**  Attempt to send Out Of Band data to a previously established network 
**  connection. Use the function code of IO$_WRITEVBLK, passing the address 
**  of the buffer to P1, and the OOB code, TCPIP$C_MSG_OOB, to P4. 
** 
*/ 
    OOBBuff = 7; 
    sysSrvSts = sys$qiow( 0,                /* efn.v | 0              */ 
                          IOChannel,        /* chan.v                 */ 
                   (1)     IO$_WRITEVBLK,    /* func.v                 */ 
                          &iosb,            /* iosb.r | 0             */ 
                          0, 0,             /* astadr, astprm: UNUSED */ 
                   (2)     &OOBBuff,         /* p1.r IO buffer         */ 
                          1,                /* p2.v IO buffer  size   */ 
                          0,                /* p3 UNUSED              */ 
                   (3)     TCPIP$C_MSG_OOB,  /* p4.v IO options flag   */ 
                          0, 0              /* p5, p6 UNUSED          */ 
                       ); 
    if((( sysSrvSts & 1  ) != 1 ) || /* Validate the system service status. */ 
       ((  iosb.cond_value & 1  ) != 1))  /* Validate the IO status. */ 
        { 
        cleanup( IOChannel ); 
        errorExit( sysSrvSts, iosb.cond_value ); 
        } 
    else 
        if( iosb.count == 0 ) 
            printf( "    FAILED to send the OOB message, no connection.\n" ); 
        else 
            printf( "    SUCCEEDED in sending the OOB message.\n" ); 
 

This example writes the data that is in the buffer.

  1. Use the IO$_WRITEVBLK function to send OOB data.
  2. Specify the buffer address of the OOB data in p1 and the length of the buffer in p2.
  3. Specify the TCPIP$C_MSG_OOB flag to indicate the type of data, in p4.

2.15 Sending Datagrams (UDP Protocol)

An application that uses UDP can send a datagram to a remote host, send broadcast datagrams to multiple remote hosts, or send multicast datagrams to members of a group.

With broadcasting, you send datagrams in one operation to multiple remote hosts on the specified subnetwork. With multicasting, you send datagrams in one operation to all hosts that are members of a particular group. The member hosts can be located on the local network or on remote networks, as long as the routers are configured to support multicasting.

2.15.1 Sending Datagrams (System Services)

You can use either of the following methods to send datagrams:

2.15.2 Sending Broadcast Datagrams (Sockets API)

You can broadcast datagrams by calling the sendto() function.

2.15.3 Sending Broadcast Datagrams (System Services)

To broadcast datagrams, use a $QIO system service command with the IO$_WRITEVBLK routine.

Before issuing broadcast messages, the application must issue the IO$_SETMODE function. This sets the broadcast option in the socket. The process must have SYSPRV, BYPASS, or OPER privilege to issue broadcast messages. However, the system manager can disable privilege checking by using the management command SET PROTOCOL UDP /BROADCAST. For more information, refer to the HP TCP/IP Services for OpenVMS Management Command Reference guide.

2.15.4 Sending Multicast Datagrams

To send IP multicast datagrams, specify the IP destination address in the range of 224.0.0.0 to 239.255.255.255 using the IO$_WRITEVBLK routine or the sendto() Sockets API function. Make sure you include the IN.H header file.

The system maps the specified IP destination address to the appropriate Ethernet or FDDI multicast address before it transmits the datagram.

You can control multicast options by specifying the following arguments to the setsockopt() Sockets API, or the IO$SETMODE system service.

For a complete list of socket options, see Appendix A.

2.16 Using the Berkeley Internet Name Domain Service

The Berkeley Internet Name Domain (BIND) service is a host name and address lookup service for the Internet. If BIND is enabled on your system, you can make a call to the BIND resolver to obtain host names and addresses.

Typically, you make a call to the BIND resolver either before you bind a socket or before you make a connection to a socket. You can also use this service to translate either the local or remote host name to an address before making a connection.

2.16.1 BIND Lookups (Sockets API)

If the BIND resolver is enabled on your system and the host name is not found in the local database, you can use either of the following functions to search the BIND database:

The host record contains both name and address information.

Example 2-24 shows how to use the gethostname() , gethostbyname() , and gethostbyaddr() functions to find a local host name and address.

Example 2-24 BIND Lookup (Sockets API)

 
#include <in.h>                     /* define internet related constants,   */ 
                                    /* functions, and structures            */ 
#include <inet.h>                   /* define network address info          */ 
#include <netdb.h>                  /* define network database library info */ 
#include <stdio.h>                  /* define standard i/o functions        */ 
#include <stdlib.h>                 /* define standard library functions    */ 
 
int main( void ) 
{ 
    char host[1024]; 
    struct in_addr addr; 
    struct hostent *hptr; 
    /* 
     * get name of local host 
     */ 
    if ( (gethostname(host, sizeof(host))) < 0 )  (1)
        { 
        perror( "Failed to get host's local name" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    printf( "Local hostname: %s\n", host ); 
 
    /* 
     * lookup local host record by name 
     */ 
 
    if ( !(hptr = gethostbyname(host)) )   (2)
        { 
        perror( "Failed to find record for local host" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    addr.s_addr = *(int *) hptr->h_addr; 
    printf( "Official hostname: %s  address: %s\n", 
            hptr->h_name, inet_ntoa(addr) ); 
 
    /* 
     * lookup local host record by address 
     */ 
 
    hptr = gethostbyaddr( &addr.s_addr, sizeof(addr.s_addr), AF_INET );  (3)
    if ( !hptr ) 
        { 
        perror( "Failed to find record for local host" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    printf( "Back-translated hostname: %s\n", hptr->h_name ); 
 
    exit( EXIT_SUCCESS ); 
} 

In this example, the following functions and arguments were used to find a local host name and address:

  1. gethostname() gets the local host name.
    host is the address of the buffer that receives the host name.
    sizeof(host) is the size of the buffer that receives the host name.
  2. gethostbyname() looks for the host record that has the specified name.
    On successful return of the gethostbyname() function, hptr receives the address of a hostent structure containing the host name, alias names, host address type, length of address (4 or 16), and an array of IPv4 addresses of the host being sought.
  3. gethostbyaddr() looks for the host record that has the specified address.
    addr.s_addr specifies the address of the host being sought. It points to a series of bytes in network order, not to an ASCII string.
    sizeof(addr.s_addr) specifies the number of bytes in the address to which the first argument points.
    AF_INET points to the IPv4 Internet address family.

2.16.2 BIND Lookups (System Services)

If BIND is enabled on your system, the IO$_ACPCONTROL system service searches the BIND database for the host name if it does not find the name in the local host database.

Example 2-25 shows how to use OpenVMS system services to find a host name and address.

Example 2-25 BIND Lookup (System Services)

 
#include <descrip.h>                /* define OpenVMS descriptors           */ 
#include <efndef.h>                 /* define 'EFN$C_ENF' event flag        */ 
#include <in.h>                     /* define internet related constants,   */ 
                                    /* functions, and structures            */ 
#include <inet.h>                   /* define network address info          */ 
#include <iodef.h>                  /* define i/o function codes            */ 
#include <netdb.h>                  /* define network database library info */ 
#include <ssdef.h>                  /* define system service status codes   */ 
#include <starlet.h>                /* define system service calls          */ 
#include <stdio.h>                  /* define standard i/o functions        */ 
#include <stdlib.h>                 /* define standard library functions    */ 
#include <string.h>                 /* define string handling functions     */ 
#include <stsdef.h>                 /* define condition value fields        */ 
#include <tcpip$inetdef.h>          /* define tcp/ip network constants,     */ 
                                    /* structures, and functions            */ 
 
struct iosb 
    {                                   /* i/o status block                 */ 
    unsigned short status;              /* i/o completion status            */ 
    unsigned short bytcnt;              /* bytes transferred if read/write  */ 
    void *details;                      /* address of buffer or parameter   */ 
    }; 
 
struct acpfunc 
    {                                   /* acp subfunction                  */ 
    unsigned char code;                 /* subfunction code                 */ 
    unsigned char type;                 /* call code                        */ 
    unsigned short reserved;            /* reserved (must be zero)          */ 
    }; 
 
 
int main( void ) 
{ 
    char host[1024]; 
    char hostent[2048]; 
    struct in_addr addr; 
    struct hostent *hptr; 
 
    struct iosb iosb;                   /* i/o status block                 */ 
    unsigned int status;                /* system service return status     */ 
    unsigned short channel;             /* network device i/o channel       */ 
 
(1)  struct acpfunc func_byaddr =        /* acp gethostbyaddr function code  */ 
        { INETACP_FUNC$C_GETHOSTBYADDR, INETACP$C_HOSTENT_OFFSET, 0 }; 
 
    struct acpfunc func_byname =        /* acp gethostbyname function code  */ 
        { INETACP_FUNC$C_GETHOSTBYNAME, INETACP$C_HOSTENT_OFFSET, 0 }; 
 
    struct dsc$descriptor p1_dsc =      /* acp function descriptor          */ 
        { 0, DSC$K_CLASS_S, DSC$K_DTYPE_T, 0 }; 
 
    struct dsc$descriptor p2_dsc =      /* acp p2 argument descriptor       */ 
        { 0, DSC$K_CLASS_S, DSC$K_DTYPE_T, 0 }; 
 
    struct dsc$descriptor p4_dsc =      /* acp p4 argument descriptor       */ 
        { 0, DSC$K_CLASS_S, DSC$K_DTYPE_T, 0 }; 
 
    $DESCRIPTOR( inet_device,           /* string descriptor with logical   */ 
                 "TCPIP$DEVICE:" );     /* name of network pseudodevice     */ 
 
    /* 
     * get name of local host 
     */ 
 
    if ( (gethostname(host, sizeof(host))) < 0 ) 
        { 
        perror( "Failed to get host's local name" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    printf( "Local hostname: %s\n", host ); 
    /* 
     * assign i/o channel to network device 
     */ 
 
    status = sys$assign( &inet_device,      /* device name                  */ 
                         &channel,          /* i/o channel                  */ 
                         0,                 /* access mode                  */ 
                         0                  /* not used                     */ 
                       ); 
 
    if ( !(status & STS$M_SUCCESS) ) 
        { 
        printf( "Failed to assign i/o channel\n" ); 
        exit( status ); 
        } 
 
    /* 
     * lookup local host record by name 
     */ 
 
(2)  p1_dsc.dsc$w_length  = sizeof(func_byname); 
    p1_dsc.dsc$a_pointer = (char *) &func_byname; 
 
    p2_dsc.dsc$w_length  = strlen( host ); 
    p2_dsc.dsc$a_pointer = host; 
 
    p4_dsc.dsc$w_length  = sizeof(hostent); 
    p4_dsc.dsc$a_pointer = hostent; 
(3)
    status = sys$qiow( EFN$C_ENF,           /* event flag                   */ 
                       channel,             /* i/o channel                  */ 
                       IO$_ACPCONTROL,      /* i/o function code            */ 
                       &iosb,               /* i/o status block             */ 
                       0,                   /* ast service routine          */ 
                       0,                   /* ast parameter                */ 
                       &p1_dsc,             /* p1 - acp subfunction code    */ 
                       &p2_dsc,             /* p2 - hostname to lookup      */ 
                       &p4_dsc.dsc$w_length,/* p3 - return length address   */ 
                       &p4_dsc,             /* p4 - output buffer address   */ 
                       0,                   /* p5                           */ 
                       0                    /* p6                           */ 
                     ); 
 
    if ( status & STS$M_SUCCESS ) 
        status = iosb.status; 
 
    if ( !(status & STS$M_SUCCESS) ) 
        { 
        printf( "Failed to find record for local host\n" ); 
        exit( status ); 
        } 
    hptr = (struct hostent *) hostent; 
    hptr->h_name += (unsigned int) hptr; 
    *(char **) &hptr->h_addr_list += (unsigned int) hptr; 
    *(char **) hptr->h_addr_list  += (unsigned int) hptr; 
 
    addr.s_addr = *(int *) hptr->h_addr; 
    printf( "Official hostname: %s  address: %s\n", 
            hptr->h_name, inet_ntoa(addr) ); 
 
    /* 
     * lookup local host record by address 
     */ 
 
    p1_dsc.dsc$w_length  = sizeof(func_byaddr); 
    p1_dsc.dsc$a_pointer = (char *) &func_byaddr; 
 
    p2_dsc.dsc$w_length  = strlen( inet_ntoa(addr) ); 
    p2_dsc.dsc$a_pointer = inet_ntoa( addr ); 
 
    p4_dsc.dsc$w_length  = sizeof(hostent); 
    p4_dsc.dsc$a_pointer = hostent; 
(4)
    status = sys$qiow( EFN$C_ENF,           /* event flag                   */ 
                       channel,             /* i/o channel                  */ 
                       IO$_ACPCONTROL,      /* i/o function code            */ 
                       &iosb,               /* i/o status block             */ 
                       0,                   /* ast service routine          */ 
                       0,                   /* ast parameter                */ 
                       &p1_dsc,             /* p1 - acp subfunction code    */ 
                       &p2_dsc,             /* p2 - ip address to lookup    */ 
                       &p4_dsc.dsc$w_length,/* p3 - return length address   */ 
                       &p4_dsc,             /* p4 - output buffer address   */ 
                       0,                   /* p5                           */ 
                       0                    /* p6                           */ 
                     ); 
 
    if ( status & STS$M_SUCCESS ) 
        status = iosb.status; 
 
    if ( !(status & STS$M_SUCCESS) ) 
        { 
        printf( "Failed to find record for local host\n" ); 
        exit( status ); 
        } 
 
    hptr = (struct hostent *) hostent; 
    hptr->h_name += (unsigned int) hptr; 
 
    printf( "Back-translated hostname: %s\n", hptr->h_name ); 
 
    /* 
     * deassign i/o channel to network device 
     */ 
 
    status = sys$dassgn( channel ); 
    if ( !(status & STS$M_SUCCESS) ) 
        { 
        printf( "Failed to deassign i/o channel\n" ); 
        exit( status ); 
        } 
 
    exit( EXIT_SUCCESS ); 
} 

This example looks up nodes by either host name or IP address.


Previous Next Contents Index