() (****************************************************************) () (Copyright (c) 1992, Carnegie Mellon University) () (All Rights Reserved) () (Permission is hereby granted to use, copy, modify, and) (distribute this software provided that the above copyright) (notice appears in all copies and that any distribution be for) (noncommercial purposes.) () (Carnegie Mellon University disclaims all warranties with regard) (to this software. In no event shall Carnegie Mellon University) (be liable for any special, indirect, or consequential damages) (or any damages whatsoever resulting from loss of use, data, or) (profits arising out of or in connection with the use or) (performance of this software.) () (****************************************************************) () (This file processed with symbol generator: 27-MAY-1991 17:12:21.83.) (Programming for CMU-OpenVMS/IP\programming_chapter)

("A reading from the Book of Armaments, Chapter 4, Verses 16 to 20:

Then did he raise on high the Holy Hand Grenade of Antioch, saying, "Bless this, O Lord, that with it thou mayst blow thine enemies to tiny bits, in thy mercy." And the people did rejoice and did feast upon the lambs and toads and tree-sloths and fruit-bats and orangutans and breakfast cereals ... Now did the Lord say, "First thou pullest the Holy Pin. Then thou must count to three. Three shall be the number of the counting and the number of the counting shall be three. Four shalt thou not count, neither shalt thou count two, excepting that thou then proceedeth to three. Five is right out. Once the number three, being the number of the counting, be reached, then lobbest thou the Holy Hand Grenade in the direction of thine foe, who, being naughty in my sight, shall snuff it."\ITALIC) (-- Monty Python, "Monty Python and the Holy Grail"\BOLD)

("The mind should be nowhere in particular"\ITALIC) (-- Takuan\BOLD) (The programming paradigm\CMUIP_PROG_1)

All I/O is done through an I/O channel to the IP: device. A channel is assigned with the SYS$ASSIGN system call. The client may then manipulate the IP mechanism by using the SYS$QIO system call to send commands to the IPACP process. There are only four functions provided which require communication between the local host and a remote host: OPEN, SEND, READ, and CLOSE. The client may OPEN a connection to a remote host then SEND and RECEIVE data and eventually CLOSE the connection.

Programmers who are used to working in a Unix environment may be wondering about the relationship between Unix "sockets" and CMU-OpenVMS/IP "connections". The NET$OPEN function is works basically like the Unix (socket) call in that it creates a local endpoint for communication. In addition, the NET$OPEN function also fills the role of the Unix (gethostbyname), (connect), (bind), and (listen) routines. The best way to think of the NET$OPEN call is to regard it as everything you need to get communication going. In a future release of CMU-OpenVMS/IP, the NET$OPEN function will be broken down into the more traditional and flexible Unix equivalents.

It is not the purpose of this chapter to explain the mechanics of the TCP-IP protocol suite. A much better understanding of these can be gained from Douglas Comer's book "Internetworking with TCP/IP". Neither is it our purpose to explain the inner workings of the CMU-OpenVMS/IP software. Those machinations are described in the chapter called Organization, (Organization_Chapter). The purpose of this chapter is to describe the IP device interface and the functionality it provides. (Assigning a channel to the IP: device\CMUIP_PROG_2)

To prepare for communication with and through the TCP/IP software, you must assign a channel to the IP device, "IP:". Simply assigning a channel does not connect you with a remote host. The syntax of the SYS$ASSIGN call is shown below: (rc = SYS$ASSIGN ( devnam , chan , [acmode] , [mbxnam] ))

The (devnam) parameter is the address of a string descriptor holding the string "IP0", and the (chan) parameter is the address of a word in which the assigned channel number is placed.

The IP device should have been previously loaded by VMS and mounted by the IPACP. (Sending requests to the IP software\CMUIP_PROG_3)

I/O requests are sent to the IP software by way of the SYS$QIO system service. The user selects the CMU-OpenVMS/IP function by passing the appropriate function code to the SYS$QIO system service, which then builds an IRP and sends it to the IP driver.

The normal sequence of events proceeds as follows: (UNNUMBERED) NET$OPEN

Initiate the connection. This may be an active or passive open depending on whether the client wants to talk to someone in particular or just wait for someone else to talk to him. NET$SEND / NET$RECEIVE

These are fairly self explanatory. NET$CLOSE / NET$ABORT

Use the Close command to clean-up the connection before dropping the channel. Use the Abort function to get away fast and dirty. (Deassigning the IP channel\CMUIP_PROG_4)

Deassigning the IP channel will send a VMS$Cancel signal to the IP device which will clean-up any outstanding I/O requests you might have forgotten about. It's also considered good practice to explicitly deassign the channel instead of letting VMS do it when the image exits. (Functionality\CMUIP_PROG_5) (TCP\CMUIP_PROG_6)

The Transmission Control Protocol is the most frequently used in the TCP/IP protocol suite. It provides a reliable stream of data between two fixed points. Integrity and order of transferred data is guaranteed, regardless of the undependability of the underlying network. Note that TCP is stream oriented, meaning that sending a buffer with x bytes in it does not guarantee that those bytes will be received all at once by the remote node's receiving process.

The Transmission Control Protocol is definitively described in RFC 793. (UDP\CMUIP_PROG_7)

The User Datagram Protocol is a packet oriented, unreliable delivery system. Data is sent in blocks and received in the same blocks, if it is received at all. This is really just straight IP with a few bells and whistles, like the port concept, tacked on. (ICMP\CMUIP_PROG_8)

The Internet Control Message Protocol is more an extension of IP than it is a sibling of TCP or UDP. For the most part, ICMP is used internally and isn't visible to the user. At times, however, certain ICMP functions are needed to perform various tasks. For instance, the PING utility sends ICMP "echo requests" to a remote hosts who is expected to return ICMP "echo reply" packets. You may create an ICMP socket with the NET$OPEN command. (IP\CMUIP_PROG_9)

IP is the foundation for all of the other protocols listed here. It provides unreliable, host-to-host datagram delivery. Direct access to the IP layer is usually only needed is either an unsupported protocol is being implemented, or you need to manually manipulate certain IP datagram header fields, like the way the TRACEROUTE program increments the IP TTL field when sending out packets. You may create an IP socket with the NET$OPEN command. (Name Resolution\CMUIP_PROG_10)

The NET$GTHST function provides 4 services: (NUMBERED) Find local hosts's Domain Name Translate a Domain Name into an IP address Translate an IP address into a Domain Name Fetch the Resource Records for a given domain. (Network Information\CMUIP_PROG_11)

The NET$STATUS, NET$INFO, and NET$DUMP function are all ways of retrieving information from the IPACP. These command allow clients to gather information about individual connections, lists of connections, device interfaces, and whathaveyou. In the future there will be an SNMP function provided with the IP driver which will provide canonical access to all of the interesting IPACP data structures. (IPACP control\CMUIP_PROG_12)

(control_sect) describes the functions which control the IPACP. With these functions the clients can send messages to the IPACP log files, change the debugging level, and cause the IPACP to exit. Not a whole lot of control when you think about, really. In the next release of CMU-OpenVMS/IP, there will be an NET$SMTP function which will provide the clients with a much greater degree of control over the IPACP. (Network Addressing\CMUIP_PROG_13)

The fundamental addressing element we are concerned with is the 32-bit IP address. Every packet sent through the IPACP has both a source and a destination IP address. Higher level protocols add the concept of ports to the addressing scheme so that each IP node has a number of "ports" to which data can be delivered. Some of these ports are reserved for standard applications, like Telnet and FTP, while others are used for arbitrary communication. (TCP destinations\CMUIP_PROG_14)

The endpoints of a TCP connection are defined when the connection is established and they never change during the life of the connection. There are two modes for opening a TCP link: active and passive.

Active opens are generally performed by client programs (as opposed to server programs). To perform an active open, the client must specify, to the NET$OPEN function, the destination host and port. The local port number may be specified but is generally specified as zero which causes the network software to randomly choose a local port. The active open allocates a local port and then sends a SYN (synchronize) packet to the specified port on the specified host. The remote host will recognize that the local host is attempting to start a connection and proceed with the three-way handshaking protocol used by TCP to initiate connections.

Passive connections are not initiated. Instead, a port is marked as waiting for a connection to be initiated. When that port receives a SYN packet, it notifies the process which performed the passive open that there is now a remote host attempting to communicate.

A good analogy for this is to picture an IP node as a house with many doors leading inside. Some of the doors have special purposes, like answering FTP requests. Imagine an FTP client. Its doing an active open means he's going to go to the right house and knock on the right door, the one with the FTP demon behind it. The reason there is an FTP demon behind it is due to the fact that the demon did a passive open on its own door, not particularly caring where the requests are going to come from. Once the knocking and answering are done, neither the client nor the demon need to worry about what their addresses or port numbers are. (Connectionless Protocols and Address Buffers\addr_buff_sect)

The other three protocols implemented by the CMU-OpenVMS/IP software are "connectionless", meaning that the source and destination addresses can change for each packet sent from a given socket. The NET$SEND function uses the Address Buffer argument to allow the client to specify an address for each packet sent. Similarly, the NET$RECEIVE function uses the Address Buffer argument to provide the client with the full address of any packet received.

The standard Address Buffer structure is simply an array of four long words. The interpretation of these long words varies depending on the protocol being used to transmit a given packet. The various interpretations are given below. (IP\CMUIP_PROG_15) (IPAddress Buffer)

Using the CMU-OpenVMS/IP software, a complete IP packet can be delivered with the client specifying as little as a single destination IP address or as much as the entire IP header, as it will be sent over the wires. All IP send requests must be accompanied by a header specification buffer. This buffer is formatted the same way that an IP header is formatted. If the EXACT bit is not set in the send command (See NET$SEND), then only the destination IP address is taken from the Header Buffer. If the EXACT bit is set, then the entire buffer will be directly copied into the beginning of the outgoing IP packet, except for the checksum field. The CHECKSUM bit in the NET$SEND command determines whether the checksum in the outgoing IP packet will be taken from the client's IP headers, or generated by the IPACP itself. (ICMP\CMUIP_PROG_16)

Clients must us the Address Buffer with the NET$SEND function in order to specify the header portion of the ICMP packet to be sent. If an address buffer is provided with the NET$RECEIVE function it will will being filled in with information about the datagram that is received. (ICMPAddress Buffer)

The format of the ICMP Address Buffer is shown in (PROG_ICMPADDR). (ICMP Address Buffer\PROG_ICMPADDR) (4\15\3\3)(name\len\off\description) (IPADR$SRC_HOST\32\0\Local host address) (IPADR$DST_HOST\32\4\Remote host address) (IPADR$TYPE\8\8\ICMP message type.) (IPADR$CODE\8\9\message ID of sorts.) (IPADR$CKSUM\16\10\Local host address.) (IPADR$SPECIAL\32\12\Interpreted based on message type.) (UDP\CMUIP_PROG_18) (UDPAddress Buffer)

The specification of a UDP address requires two IP addresses, local and remote, as well as two port numbers, local and remote. If an address buffer is provided with the NET$RECEIVE function it will will being filled in with information about the datagram that is received. (PROG_UDPADDR) describes the format of the UDP address buffer.

(UDP Address Buffer\PROG_UDPADDR) (4\15\3\3)(name\len\off\description) (IPADR$SRC_HOST\32\0\Local host address.) (IPADR$DST_HOST\32\4\Remote host address.) (IPADR$SRC_PORT\16\8\Local port) (IPADR$DST_PORT\16\10\Remote port) (Network User Function Codes\Functions_sect)

This section explains the semantics of the various functions performed by the IP device. The functions on the next few pages are organized to look like function calls: NET$OPEN(p1,p2,p3,p4,p5,p6)

but in actuality, they simply denote parameters to be passed to the SYS$QIO system service: SYS$QIO([efn],chan,func,[iosb],[astadr],[astprm],p1,p2,p3,p4,p5,p6)

An example of the NET$CLOSE function might look like this: RC = SYS$QIO(0,net_chan,NET$CLOSE,0,0,0, 1,0,0,0,0,0) (Network User Function Codes\\NEWPAGE) (QIO_ROUTINE\doublerunningheads) (NET$OPEN (IO$_Create)\Create a Network Socket\\CMUIP_PROG_20) Create an endpoint for internet communication (NET$OPEN) (FHnam(p1),Foreign_Prt(p2),Local_Prt(p3), Flags(p4),Protocol(p5),TimOut(p6)) (p1\cond_value\longword integer\read only\by reference) The address of a null terminated string containing the domain name of the foreign host. If the (AddrFlag) (see P4 below) is set, then (P1) is interpreted as the 32-bit IP address of the host that is to be the destination for this connection. (p2\cond_value\longword integer\read only\by value) The foreign port number. If set to 0 on a passive open, the foreign port will be chosen by the remote system.

If set to 0 on an active TCP open, the connection will fail. (p3\cond_value\longword integer\read only\by value) The local port number. If set to 0, the local port will be chosen by the local system.

(IP\BOLD): This is the protocol filter for this IP socket. Only IP packets with this value in the protocol field will be delivered when the client reads from the network. A value of zero (0) specifies a wildcard filter. (p4\cond_value\longword integer\read only\by value) Open Flags. (PROG_OPEN_FLAGS) shows the possible values for (P4).

(Valid flags for TCP$OPEN\PROG_OPEN_FLAGS) (4\10\3\4) (Name\Bit\Prot\Meaning) (Mode\0\TCP\When set, initiate connect by sending SYN segment When clear, wait for SYN segment) (Mode\0\UDP\When set, addresses stored in in data buffer When clear, addresses passed in an Address Structure.) (OpenNoWait\1\all\If set, wait for connection completion If clear, return immediately.) (Addrflag\2\all\If set, the value in P1 (FHnam) is treated as a 32-bit IP address. If this bit is clear, P1 is interpreted as the address of a string descriptor containing the destination's domain name.) (p5\cond_value\longword integer\read only\by value) Protocol code. Any communication performed with the connection will use the protocol specified here. The valid protocol codes are shown in (PROG_PROTCODES).
(Valid protocol codes\PROG_PROTCODES) (3\15\3) (Code\Value\Protocol Name) (U$TCP_Protocol\0\Transmission Control Protocol) (U$UDP_Protocol\1\User Datagram Protocol) (U$ICMP_Protocol\2\Internet Control Message Protocol) (U$IP_Protocol\3\Internet Protocol) (p6\cond_value\longword integer\read only\by value) Connection inactivity timeout in seconds.

The Open can be initiated in one of two ways, either actively or passively. The active open attempts to initiate a connection to a port on a specific remote system. The passive open is used to wait for a connection requests from any remote system for a specific local port.

Normally, servers perform passive opens on a well known socket waiting to serve requests from any remote system. And user programs actively open a network connection to a remote well known port to obtain service from a server on a remote system. (SS$_NORMAL\Indicates successful completion) (SS$_MEDOFL\Media is off-line, ACP has died.) (SS$_ACCVIO\Unable to access HOST name string.) (SS$_BADPARAM\Host name string + null byte > 128 characters.) (SS$_EXQUOTA\unable to allocate ACP argument blk.) (SS$_INSFMEM\Same as SS$_EXQUOTA.) (IOSB RETURN CODES) (NET$_IPC\Illegal Protocol Code) (NET$_FSU\Foreign Host Unspecified) (NET$CLOSE (IO$_Delete)\Terminate a network connection\\CMUIP_PROG_23) Close an established connection gracefully (NET$CLOSE) (Flags(p1)) (p1\cond_value\longword integer\read only\by value)

The Close function is used to gracefully close an established connection. Any data that may still be in transit will be delivered before the connection is fully closed. (SS$_NORMAL\Indicates successful completion) (SS$_MEDOFL\Media off-line, ACP is not running.) (SS$_BADPARAM\Invalid Local Connection ID (<= 0).) (SS$_EXQUOTA\Unable to allocate ACP argument block.) (SS$_INSFMEM\same as SS$_EXQUOTA.) (IOSB RETURN CODES) (SS$_NORMAL\Indicates successful completion) (NET$_CDE\Connection does not exist) (NET$_CC\Connection Closing) (NET$ABORT (IO$_Deaccess)\Abort a connection\\CMUIP_PROG_24) Terminate a connection abnormally (NET$ABORT) () (NONE)

The abort function is used to terminate a connection abnormally. Any data that may still be in transit may be lost when a connection is aborted. (SS$_NORMAL\Indicates successful completion) (SS$_MEDOFL\Media off-line, ACP is not running.) (SS$_EXQUOTA\Unable to allocate ACP argument block.) (SS$_INSFMEM\same as SS$_EXQUOTA.) (IOSB RETURN CODES) (SS$_NORMAL\Indicates successful completion) (NET$_CDE\Connection does not exist) (NET$_CC\Connection Closing) (NET$SEND (IO$_WriteVBlk)\Transmit Data\\CMUIP_PROG_25) (NET$SEND) (function codesNET$SEND) Send data to a remote host (NET$SEND) (BufAdrs(p1),BufSize(p2),Flags(p4), Urgent(p5),Addr_Spec(p6)) (p1\cond_value\longword integer\read only\by value) The starting virtual address of the buffer that contains the data being transmitted over the network. If P2 specifies a zero-length buffer, P1 is ignored. (p2\cond_value\longword integer\read only\by value) The size of the buffer in bytes. A zero-length buffer will be ignored. (p4\cond_value\longword integer\read only\by value) Flags. When using TCP, setting the first bit of this argument will cause all TCP data to be flushed to the network. Also known as the End-Of-Line (EOL) flag.

(IP\BOLD): this argument is interpreted differently. The first bit of this argument is the EXACT flag and the second bit is the CKSUM flag. See (addr_buff_sect) for a description of these flags. (p5\cond_value\longword integer\read only\by value) (TCP\BOLD): Urgent Flag. Marks this data as TCP "urgent" data (such as a ^C in Telnet). Not meaningful unless used with with a TCP connection. Not yet implemented.

(IP\BOLD): This is the size of the IP header provided in P6 (in longwords). (p6\cond_value\Address Buffer\read only\by reference) (UDP,ICMP\BOLD): The starting virtual address of an Address Buffer. This allows the connectionless protocols, UDP and ICMP, to specify destination addresses for each SEND command, as opposed to connection-oriented protocols, like TCP, which require a single destination address to be determined at connection startup time. See (addr_buff_sect) for details.

(IP): this is the starting virtual address of a buffer that contains the IP header.

The Send function is used to send data to a remote port. Since I/O on VMS is asynchronous, a send and a receive can be pending on the same TCP connection at the same time. (SS$_NORMAL\Indicates successful completion) (SS$_MEDOFL\Network ACP not running) (SS$_BADPARAM\Invalid Local Connection ID (<= 0)) (SS$_EXQUOTA\Unable to allocate ACP Arg block or Buffer TOO large) (SS$_INSFMEM\Unable to allocate ACP argument block) (SS$_ACCVIO\Buffer access violation) (SS$_ILLCNTRLFUNC\Illegal ACP function code. (Internal Error)) (IOSB RETURN CODES) ((Not provided at the present time)) (NET$RECEIVE (IO$_ReadVBlk)\Receive Network Data\\CMUIP_PROG_26) Fill buffer with data received from network. (NET$RECEIVE) (BufAdrs(p1),BufSize(p2),Addr_Spec(p3)) (p1\cond_value\longword integer\read only\by value) The starting virtual address of a buffer which is to hold the incoming data. (p2\cond_value\longword integer\read only\by value) The size, in bytes, of the buffer specified in p1. (p3\cond_value\Address Buffer\write only\by reference) The optionally supplied starting address of an Address Buffer. If given, additional information about the data received will be written into this buffer. See (addr_buff_sect) for further details.

When a receive function code is issued, the user-specified buffer is filled with data from the associated network connection. A read is terminated if either of the following conditions occur: (UNNUMBERED) The user buffer is full. An EOL (end-of-line) segment is received on a TCP connection. A datagram is received by a UDP, ICMP, or IP connection.

Note: A TCP connection is a stream of eight bit bytes. There is no logical end of record associated with a TCP connection. A write of 123 bytes on one end of the connection will not necessarily result in a 123 byte record showing up on the remote end. If a programmer or protocol designer wants to logically delimit data, on a TCP connection, he/she must devise a method of encoding that information in the higher level protocol. (SS$_NORMAL\Indicates successful completion) (SS$_MEDOFL\Network ACP not running) (SS$_BADPARAM\Invalid Local Connection ID (<= 0)) (SS$_EXQUOTA\Unable to allocate ACP Arg block or Buffer TOO large) (SS$_INSFMEM\Unable to allocate ACP argument block) (SS$_ACCVIO\Buffer access violation) (SS$_ILLCNTRLFUNC\Illegal ACP function code. (Internal Error)) (IOSB RETURN CODES) ((Not provided at the present time)) (NET$STATUS (IO$_ACPcontrol)\obtain connection information\\CMUIP_PROG_27)

Obtain information about the connection (NET$STATUS) (buff_addr(p1),buff_size(p2)) (p1\cond_value\longword integer\read only\by value) Buffer Address. The starting virtual address of a buffer into which status information is to be written. (p2\cond_value\longword integer\read only\by value) Buffer Size. The size, in bytes, of the buffer in P1.

The network status function is used to obtain information about the connection, such as the state of the connection, the number of bytes available to be read, and the send and receive window size.

The connection must be an established TCP connection before the Status network function can be used. The Status network function can not be used on UDP connections nor on TCP connections that are not yet fully established.

Once the buffer has been filled, the format is: +---------------------------------------------------------------+ | CS$Last_State | CS$State | CS$Bytes_Avail | +---------------------------------------------------------------+ | CS$Send_Window | +---------------------------------------------------------------+ | CS$Recv_Window | +---------------------------------------------------------------+ | CS$Owner_PID | +---------------------------------------------------------------+

(2\20) (Field\Description) (CS$Bytes_Avail\The number of bytes received by the ACP protocol but not yet read in by the process. The number of bytes in the input buffer.) (CS$State\The current state of the connection. (UNNUMBERED) CS$Closed CS$Listen CS$Syn_Send CS$Syn_Recv CS$Established CS$Fin_Wait_1 CS$Fin_Wait_2 CS$Time_Wait CS$Close_Wait CS$Closing CS$Last_Ack CS$Reset CS$Inactive ) (CS$Last_State\The state that the connection was in previous to the current state.) (CS$Send_Window\The number of data bytes that the remote TCP is willing to immediately accept.) (CS$Recv_Window\The number of data bytes that we are currently willing to accept from a remote site.) (CS$User_ID\) (SS$_NORMAL\Indicates successful completion) (SS$_MEDOFL\Network ACP not running) (SS$_BADPARAM\Invalid Local Connection ID (<= 0)) (SS$_EXQUOTA\Unable to allocate ACP Arg block or Buffer TOO large) (SS$_INSFMEM\Unable to allocate ACP argument block) (SS$_ACCVIO\Buffer access violation) (SS$_ILLCNTRLFUNC\Illegal ACP function code. (Internal Error)) (IOSB RETURN CODES) ((Not provided at the present time)) (NET$INFO (IO$_Modify)\Describe connection endpoints\\CMUIP_PROG_28) The INFO function returns the hosts and ports being used by the channel (NET$INFO) (buff_addr(p1),buff_size(p2)) (p1\cond_value\longword integer\read only\by value) Buffer Address. The starting virtual address of a buffer into which the information is to be written. (p2\cond_value\longword integer\read only\by value) Buffer Size. The size, in bytes, of the buffer in P1.

The network INFO function can only be used once the UDP or TCP connection has been NET$OPENed.

The format of the returned buffer is shown in (PROG_INFOFIGURE).

(Format of the buffer used for NET$INFO\PROG_INFOFIGURE) (KEEP) (KEEP) 15 8 7 0 +------------------------------------------------------------+ | CI$LHost_Name_Size | CI$FHost_Name_Size | +------------------------------------------------------------+ | | ~ CI$Foreign_Host (128 Bytes) ~ | | +------------------------------------------------------------+ | CI$Foreign_Port | +------------------------------------------------------------+ | Not Used | +------------------------------------------------------------+ | | ~ CI$Local_Host (128 Bytes) ~ | | +------------------------------------------------------------+ | CI$Local_Port | +------------------------------------------------------------+ | Not Used | +------------------------------------------------------------+ | | +-------- CI$Local_Internet_Adrs -------+ | | +------------------------------------------------------------+ | | +-------- CI$Remote_Internet_Adrs -------+ | | +------------------------------------------------------------+
(2\30) (Field\Description) (CI$FHost_Name_Size\The length in bytes of the name of the foreign host.) (CI$LHost_Name_Size\The length in bytes of the name of the local host.) (CI$Foreign_Host\The name of the foreign host.) (CI$Foreign_Port\The number of the port on the foreign host.) (CI$Local_Port\The number of the port on the local host.) (CI$Local_Host\The name of the local host.) (CI$Local_Internet_Adrs\The 32 bit internet address of the local host.) (CI$Remote_Internet_Adrs\The 32 bit internet address of the remote host.) (SS$_NORMAL\Indicates successful completion) (SS$_MEDOFL\Network ACP not running) (SS$_BADPARAM\Invalid Local Connection ID (<= 0)) (SS$_EXQUOTA\Unable to allocate ACP Arg block or Buffer TOO large) (SS$_INSFMEM\Unable to allocate ACP argument block) (SS$_ACCVIO\Buffer access violation) (SS$_ILLCNTRLFUNC\Illegal ACP function code. (Internal Error)) (IOSB RETURN CODES) ((Not provided at the present time)) (NET$GTHST (IO$_SkipFile)\Host Name translation\\CMUIP_PROG_29) The Get Host function is useful for translating IP addresses to host names and translating host names into IP addresses. (NET$GTHST) (buff_addr(p1),buff_size(p2),func(p3), parm1(p4),parm2(p5),parm3(p6)) (p1\cond_value\longword integer\read only\by value) Buffer Address. The starting virtual address of a buffer into which the information is to be written. (p2\cond_value\longword integer\read only\by value) Buffer Size. The size, in bytes, of the buffer in P1. (p3\cond_value\longword integer\read only\by value) Function code. Determines the type of translation to be performed:
(3\20\3) (GTH_LCLHST\0\Local host information) (GTH_NAMADR\1\Name to Address translation) (GTH_ADRNAM\2\Address to Name translation) (GTH_RRLOOK\3\Name to Resource Record translation) (p4\cond_value\longword integer\read only\by value) Function-specific parameter. If the P3 parameter is GTH_NAMADR or GTH_RRLOOK, P4 will be the address of the ASCIZ name. If the P3 parameter is GTH_ADRNAM, P4 will be the 32-bit IP address whose name we want to look up. (p5\cond_value\longword integer\read only\by value) Function-specific parameter. If the P3 parameter is GTH_RRLOOK, P5 will specify the type of Resource Record we want to look-up. (p6\cond_value\longword integer\read only\by value) Function-specific parameter. undefined for all current functions.

If the P3 argument indicates address to host name translation, upon successful completion the buffer will look like this: 31 0 +------------------------------------------------------------+ | AL$NAMLEN | +------------------------------------------------------------+ | AL$NAMSTR | ~ ~ | | +------------------------------------------------------------+

(2\30) (Field\Description) (AL$NAMLEN\The length of the Domain Name.) (AL$NAMSTR\The Domain Name.)

If the P3 argument indicates Name to Address translation, or Local Host information, upon successful completion the buffer will look like this: 31 0 +------------------------------------------------------------+ | GH$NL_ADRCNT | +------------------------------------------------------------+ | GH$NL_ADRLST | ~ ~ | | +------------------------------------------------------------+

(2\30) (Field\Description) (GH$NL_ADRCNT\The number of addresses associated with this host. A host can have more than one address.) (GH$NL_ADRLST\A sequence of 32 bit IP addresses.)

If the P3 argument indicates Name to RR translation, upon successful completion the buffer will look like this: 15 0 +------------------------------------------------------------+ | GH$RL_RDLEN | +------------------------------------------------------------+ | GH$RL_RDATA | ~ ~ | | +------------------------------------------------------------+

(2\30) (Field\Description) (GH$RL_RDLEN\Resource data length.) (GH$RL_RDATA\RData followed by name.) (IOSB RETURN CODES) ((Not provided at the present time)) (NETWORK CONTROL FUNCTION CODES\control_sect)

The function listed in this section are privileged and are used to control and monitor the IPACP. The calling mechanism is identical to the calling mechanism for the user-level function and is described in (Functions_sect) (Network Control Function Codes\\NEWPAGE) (NET$DUMP (IO$_Unload)\Fetch Network Info\\CMUIP_PROG_30) Retrieve information from the IPACP. (NET$DUMP) (BufAdrs,BufSize,Dfunc,arg0) (p1\cond_value\longword integer\read only\by value) Buffer Address. The starting virtual address of a buffer into which status information is to be written. (p2\cond_value\longword integer\read only\by value) Buffer Size. The size, in bytes, of the buffer in P1. (p3\cond_value\longword integer\read only\by value) Sub-function code. This value determines what type of information is retrieved from the IPACP. (p4\cond_value\longword integer\read only\by value) Sub-function argument 0. This is a long word that is passed to the sub-function. (p5\cond_value\longword integer\read only\by value) Sub-function argument 1. This is a long word that is passed to the sub-function. (p6\cond_value\longword integer\read only\by value) Sub-function argument 2. This is a long word that is passed to the sub-function.

This function dumps information from the IPACP to a client process. PHY_IO privilege is required to use this function.

The (sub-function) parameter determines the type of information returned. The possible sub-functions are shown in (PROG_DUMPSUBF).

(Dump sub-functions\PROG_DUMPSUBF) (3\25\3)(Function\Code\Description) (DU$Dynamic_Mem_Alloc\1\Memory management counters) (DU$TCP_Stats\2\TCP statistic counters) (DU$Local_Connection_ID\3\List of active TCP connections) (DU$TCB_Dump\4\Contents of a TCB) (DU$Host_Stats\5\obsolete, unused) (DU$Known_Host_Index\6\obsolete, unused) (DU$Device_Dump\7\Device status) (DU$UDP_Connections\8\List of UDP connections) (DU$UDPCB_Dump\9\Contents of a UDPCB) (DU$ARP_Cache\10\Contents of ARP cache) (DU$ICMP_Connections\11\List of ICMP connections) (DU$ICMPCB_Dump\12\Contents of a ICMPCB) (DU$IP_Connections\13\List of IP connections) (DU$IPCB_Dump\14\Contents of a IPCB) (DU$Device_List\15\List of IP interfaces) (DU$Device_Stat\16\Dump of dev config entry)

Peculiarities of the various sub-functions are described below: (DU$Dynamic_Mem_Alloc\CMUIP_PROG_32)

Takes no arguments. Returns a D$Mem_Alloc_Return_blk. (DU$TCP_Stats\CMUIP_PROG_33)

Takes no arguments. Returns a D$TCP_Stats_Return_Blk. (DU$Local_Connection_ID\CMUIP_PROG_34)

Takes no arguments. Returns a vector of longwords containing the indices of valid TCP connection blocks within the IPACP. The first longword contains a count of the remaining longwords. (DU$TCB_Dump\CMUIP_PROG_35)

ARG0 is the index of the TCB for which information is desired. Returns a D$TCB_Dump_Return_Blk. (DU$Host_stats\CMUIP_PROG_36)

Obselete. (DU$Known_Host_Index\CMUIP_PROG_37)

Obselete. (DU$UDP_Connections\CMUIP_PROG_38)

Takes no arguments. Returns a vector of longwords containing the indices of valid UDPP connection blocks within the IPACP. The first longword contains a count of the remaining longwords. (DU$UDPCB_Dump\CMUIP_PROG_39)

ARG0 is the index of the UDPCB for which information is desired. Returns a D$UDPCB_Dump_Return_Blk. (DU$ARP_Cache\CMUIP_PROG_40)

Obselete. (DU$ICMP_Connections\CMUIP_PROG_41)

Takes no arguments. Returns a vector of longwords containing the indices of valid UDPP connection blocks within the IPACP. The first longword contains a count of the remaining longwords. (DU$ICMPCB_Dump\CMUIP_PROG_42)

ARG0 is the index of the ICMPCB for which information is desired. Returns a D$ICMPCB_Dump_Return_Blk. (DU$IP_Connections\CMUIP_PROG_43)

Takes no arguments. Returns a vector of longwords containing the indices of valid UDPP connection blocks within the IPACP. The first longword contains a count of the remaining longwords. (DU$IPCB_Dump\CMUIP_PROG_44)

ARG0 is the index of the ICMPCB for which information is desired. Returns a D$ICMPCB_Dump_Return_Blk. (DU$Device_List\CMUIP_PROG_45)

Takes no arguments. Returns a vector of longwords containing the indices of valid device interfaces within the IPACP. The first longword contains a count of the remaining longwords. (DU$Device_Stat\CMUIP_PROG_46)

ARG0 is the index of the ICMPCB for which information is desired. Returns a D$Dev_Dump_Return_Blk. (SS$_NORMAL\Indicates successful completion) (NET$EXIT (IO$_Release)\Kill IPACP\\CMUIP_PROG_47) Cause the IPACP process to clean-up and expire. (NET$EXIT) (none) (NONE)

Causes the IPACP to terminate all connections and exit. This is the preferred method of shutting down the IPACP process. The exit function is used to gracefully bring down the ACP. This function requires the PHY_IO privilege. There are no special parameters for this I/O function. PHY_IO privilege is required to use this function. (SS$_NORMAL\Indicates successful completion) (SS$_MEDOFL\Network ACP not running) (SS$_EXQUOTA\Unable to allocate ACP Arg block or Buffer TOO large) (SS$_INSFMEM\Unable to allocate ACP argument block) (IOSB RETURN CODES) (SS$_NORMAL\Indicates successful completion) (NET$DEBUG (IO$_Diagnose)\Set Debugging Level\\CMUIP_PROG_48) The debug function is used to set the debug level in the ACP. (NET$DEBUG) (Level(p1)) (p1\cond_value\longword integer\read only\by value) New Debug Mask. If function is successful, P1 will be the mask used by the IPACP.

Each bit in the mask corresponds to a different type of event which is monitored by the IPACP. If the bit is set, the IPACP will write a record of the events to a log file, pointed to by INET$LOG. PHY_IO privilege is required to use this function.

(PROG_DEBUGFLAGS) shows the meaning of each bit in the debug mask.

(Debug Flags Mask\PROG_DEBUGFLAGS) (3\14\7) (Name\Mask\Logs these events) (LOG$PHY\%X'01'\Packet physical headers) (LOG$ARP\%X'02'\ARP packet info) (LOG$IP\%X'04'\IP packet headers) (LOG$TCP\%X'08'\TCP segment info (packet trace)) (LOG$TCBDUMP\%X'10'\TCB dump on servicing) (LOG$USER\%X'20'\User I/O requests) (LOG$TCBSTATE\%X'40'\TCB state changes) (LOG$TCBCHECK\%X'80'\TCB servicing timing) (LOG$TCPERR\%X'100'\TCP errors (dropped pkts etc.)) (LOG$ICMP\%X'200'\ICMP activity) (LOG$UDP\%X'400'\UDP activity) (LOG$TVT\%X'800'\TVT (virtual terminal) activity) (LOG$IPERR\%X'1000'\IP errors (bad routing etc.)) (SS$_NORMAL\Indicates successful completion) (SS$_MEDOFL\Network ACP not running) (SS$_EXQUOTA\Unable to allocate ACP Arg block or Buffer TOO large) (SS$_INSFMEM\Unable to allocate ACP argument block) (IOSB RETURN CODES) (SS$_NORMAL\Indicates successful completion) (NET$EVENT (IO$_WriteCheck)\Log an Event\\CMUIP_PROG_50) Tell the IPACP to record a message in the INET$ACTIVITY log. (NET$EVENT) (buff_addr(p1),buff_size(p2)) (p1\cond_value\longword integer\read only\by value) Buffer Address. The starting virtual address of a buffer in which the information to be logged is stored. (p2\cond_value\longword integer\read only\by value) Buffer Size. The size, in bytes, of the buffer in P1.

The contents of the buffer will be written to the activity log, INET$ACTIVITY, preceded by the date and process ID. This function is used by FTP to log file accesses and by FINGER to record queries. PHY_IO privilege is required to use this function. (SS$_NORMAL\Indicates successful completion) (SS$_MEDOFL\Network ACP not running) (SS$_BADPARAM\Bad buffer size) (SS$_INSFMEM\Unable to allocate ACP argument block) (SS$_ACCVIO\Buffer access violation) (SS$_ILLCNTRLFUNC\Illegal ACP function code. (Internal Error)) (IOSB RETURN CODES) (SS$_NORMAL\Indicates successful completion) (NETWORK IO STATUS BLOCK\CMUIP_PROG_51) +--------------------------------+-------------------------------+ | Bytes Transferred | Status | +--------------------------------+-------------------------------+ | IPACP Status | +--------------------------------+-------------------------------+ (UNNUMBERED) Status - The final status of the I/O request. If the status is SS$_ABORT the second longword will contain some additional information. Bytes Transferred - The number of bytes retrieved in a successful read. IPACP Status - If the value in the first word of the IOSB is SS$_ABORT this field will contain additional status information. The value in this field can be treated as any other custom VMS system error code. Your utility should link in NETERROR.OBJ. This file can easily be created from the file NETERROR.MSG by the VAX/VMS Message Utility. (PROGRAMMING EXAMPLES\CMUIP_PROG_52)

The program below implements a discard server. The discard protocol, fully described in RFC 863, merely throws away any data received. This continues until the remote site closes the connection.

MODULE Discard_Server ( Language (Bliss32), List (Assembly, NoBinary, NoExpand), MAIN = Discard_Server_Main) = BEGIN !++ ! Discard_Server.B32 ! ! Description: ! ! Implement a server for the discard protocol. ! - Do a passive open on the well known discard socket ! - Read some bytes ! - Upon EOF, netclose and exit ! ! Written By: Dale Moore 25-JUL-1986 CMU-CS/RI ! ! Modifications: ! !-- LIBRARY 'SYS$LIBRARY:STARLET'; LIBRARY 'SYS$LIBRARY:NETWORK'; OWN Channel : WORD UNSIGNED, ! The I/O channel Read_Buffer : VECTOR [512, BYTE], ! The hold read data IOSB : $BBLOCK [8]; ! I/O Status Block ROUTINE Discard_Server_Main = !++ ! Functional Description: ! ! The main entry routine. Assign the network ! protocol device and do a passive open on the ! discard socket. !-- BEGIN LOCAL Status; Status = $ASSIGN (CHAN = Channel, DEVNAM = %ASCID 'IP:'); IF NOT .Status THEN Signal_Stop (.Status); Status = $QIO ( CHAN = .Channel, FUNC = TCP$OPEN, IOSB = IOSB, ASTADR = Discard_Open_AST, P3 = 9, ! Discard Port P4 = 0); ! Flags IF NOT .Status THEN Signal (.Status); !++ ! The rest of the program is done at AST level. ! The SYS$HIBER system call in no way blocks AST's. !-- $HIBER END; FORWARD ROUTINE Do_Discard_Read; ROUTINE Discard_Open_AST = !++ ! Functional Description: ! ! Our passive network OPEN has completed. ! Make sure that it has completed successfully ! before starting to receive the data. !-- BEGIN LOCAL Status; Status = .IOSB [0, 0, 16, 0]; IF NOT .Status THEN Signal_Stop (.IOSB [4, 0, 32, 0], 0, .Status); Do_Discard_Read (); SS$_NORMAL END; ROUTINE Discard_Read_AST = !++ ! Functional Description: ! ! A read has completed. First check the I/O Status ! Block of the read to see if the connection is still alive. ! Second issue another read on the same buffer. !-- BEGIN LOCAL Status; Status = .IOSB [0, 0, 16, 0]; IF NOT .Status THEN Signal_Stop (.IOSB [4, 0, 32, 0], 0, .Status); Do_Discard_Read (); SS$_NORMAL END; ROUTINE Do_Discard_Read = !++ ! Functional Description: ! ! Get ready to receive some bytes. !-- BEGIN LOCAL Status; Status = $QIO ( CHAN = .Channel, FUNC = TCP$RECEIVE, IOSB = IOSB, ASTADR = Discard_Read_AST, P1 = Read_Buffer, P2 = %ALLOCATION (Read_Buffer)); IF NOT .Status THEN Signal (.Status); SS$_NORMAL END; END ELUDOM

A brief description of the code example: (CALLOUT) The NETWORK.L32 library provides use with useful macros and structure definitions. Assign a channel to the IP device Passive open on channel. Go into hibernation state. The rest of the program is executed asynchronously. Read data from the network.