HPUX socketx25[7]

socketx25(7) socketx25(7)
Requires Optional LAN/X.25 Software
NAME
socketx25 - Interprocess communications via AF_CCITT sockets
DESCRIPTION
Sockets are communication endpoints that allow processes to
communicate either locally or remotely. They are accessed by means of
a set of system calls (see socket(2)). The discussion below describes
ioctl(2) calls available when directly accessing the X.25 Packet level
(level 3) via sockets.
That is, when the sockets are in the address family AF_CCITT. Refer
to the af_ccitt(7F) manual entry for details.
COMMAND FUNCTIONS
The following ioctl(2) requests are defined in <x25/x25ioctls.h>:
X25_RD_HOSTADR
Loads the X.121 address of an X.25 interface on the local
host into an x25addrstr struct. Example:
struct x25addrstr bind_addr;
bind_addr.ifname[0] = '\0';
error = ioctl(s,X25_RD_HOSTADR,&bind_addr);
X25_WR_MASK_DATA
Sets a bit mask to be anded with Protocol-IDs for address-
matching during a bind() call. Each byte of the bit mask is
set in an entry in the x25_mask[] array in an x25_mask_data
data structure. The length (in bytes) of the bit mask is
stored in the x25_masklen field of an x25_mask_data data
structure. x25_mask_data is defined in the x25str.h header
file. For example, to set an address mask accepting
Protocol-IDs in the range 0xc033 to 0xcf33:
int s;
struct x25_mask_data in_parms;
in_parms.x25masklen = 2;
in_parms.x25_mask[0] = 0xf0;
in_parms.x25_mask[1] = 0xff;
error = ioctl(s, X25_WR_MASK_DATA, &in_parms);
X25_RESET_VC
Resets a Virtual Circuit (VC) associated with a particular
socket, which might cause data loss. Issuing this call
sends an out-of-band event (OOB_VC_RESET) to the peer user.
If blocking I/O is being used, ioctl() blocks until an
acknowledgement is received from the remote node. Example:
error = ioctl(s, X25_RESET_VC, 0);
X25_SEND_TYPE
Sets the D-bit or the Q-bit in a sequence of X.25 packets.
Hewlett-Packard Company - 1 - HP-UX Release 9.0: August 1992
socketx25(7) socketx25(7)
Requires Optional LAN/X.25 Software
Also controls whether the next send(2) will send a complete
or a partial X.25 message via the More-Data-To-Follow (MDTF)
bit setting. On Series 700/800 systems, setting the D-bit
lets the sending process indicate that it requires
acknowledgement when the end of a message has been received.
If a Series 700/800 system receives a data packet with the
D-bit set and the socket has been set to permit D-bit
operations, it will ackowledge only when the receiving
process has read the data. If a Series 300/400 system
receives a data packet with the D-bit set, it acknowledges
automatically, without guaranteeing that the receiving
process has read the data. Any attempt to set the D-bit on
a Series 300/400 system is rejected and the error [EINVAL]
is returned.
Setting the Q-bit indicates that the data being sent is
significant to a device connected to the remote host. Set
these bits by shifting the appropriate bit mask to the left
one bit and ORing the mask with a user-defined send_type
variable as in this example:
int s, send_type, error;
send_type |= 1<<X25_Q_BIT; /* set Q*/
or
send_type |= 1<<X25_D_BIT; /* set D*/
error = ioctl(s, X25_SEND_TYPE, &send_type);
To use the D-bit or Q-bit, they must be set before the first
send() in a message. Use X25_SEND_TYPE to set the D-bit
prior to connect, or X25_SEND_CALL_ACCEPT to set the
connection to permit use of D-bit data sends.
To send a partial X.25 message, MDTF bit should be set to 1.
To send the final segment or to flush out a complete
message, the MDTF bit should be reset to 0 before the
send(2). Example:
int socket, send_type, first_msglen,
second_msglen, third_msglen;
u_char *first_msg, second_msg, third_msg;
/* set MDTF indicator to indicate multiple message
* fragments ....
*/
send_type = 1 << X25_MDTF_BIT;
ioctl(socket,X25_SEND_TYPE,&send_type);
/* send the first two message fragments ....
*/
Hewlett-Packard Company - 2 - HP-UX Release 9.0: August 1992
socketx25(7) socketx25(7)
Requires Optional LAN/X.25 Software
return = send(socket, first_msg, first_msglen, 0);
return = send(socket, second_msg, second_msglen, 0);
/* now clear the MDTF indicator ....
* and send the third (final) message fragment ...
*/
send_type = 0;
ioctl(socket,X25_SEND_TYPE,&send_type);
return = send(socket, third_msg, third_msglen, 0);
NOTE: The values of the Q bit and the D bit must remain
constant throughout a complete X.25 message sequence.
Therefore, the values of the D and Q bits are latched from
the first X25_SEND_TYPE ioctl(), and any attempt to change
them during transfer is ignored.
X25_NEXT_MSG_STAT
Returns status information on the next-available (unread)
message, such as its size, whether message is partial or
complete, whether the D and Q bits are set, and whether
Call-user or clear data is available. This information is
returned in an x25_msg_statstruct. Example:
/* Globals
*/
int MDTF;
char *malloc();
......
int socket, count;
unsigned int length;
char *fragment;
struct x25_msg_stat next_msg_stat;
ioctl(socket, X25_NEXT_MSG_STAT, &next_msg_stat);
if (next_msg_stat.x25_msg_flags &
(1 << X25_MDTF_BIT)) {
/* this is a fragment of the complete X.25
message ...
*/
MDTF = TRUE;
printf( More Data To Follow ....0);"
} /* if next_msg_stat .... */
else {
/* MDTF indicator is not set, use the MDTF
* global to determine if this the final
* fragment in a message sequence or a complete
* message sequence ....
*/
if (MDTF == TRUE) {
/* this is the final fragment in the message
Hewlett-Packard Company - 3 - HP-UX Release 9.0: August 1992
socketx25(7) socketx25(7)
Requires Optional LAN/X.25 Software
* sequence ....
*/
printf( Final fragment of X.25 message
printf( .0);"
} /* if MDTF == TRUE .... */
else {
/* this is a complete X.25 message sequence.
*/
printf( Complete X.25 message received.0);"
} /* else MDTF == FALSE .... */
/* now set MDTF to FALSE ....
*/
MDTF = FALSE;
/* get state of D and Q bits
*/
if (next_msg_stat.x25_msg_flags & (1<<X25_D_BIT)) {
/* D bit for this sequence has been set ....
*/
printf( , D bit set for
}
if (next_msg_stat.x25_msg_flags & (1<<X25_Q_BIT)) {
/* Q bit for this sequence has been set ....
*/
printf( , Q bit set for
}
} /* else next_msg_stat .... */
/* now get enough memory to receive the message ....
*/
length = (unsigned int)next_msg_stat.x25_msg_size;
message = malloc(length);
if (message == NULL) {
/* malloc couldn't get memory ....
*/
}
count = recv(socket, message, (int) length, 0);
Note that the Q bit value remains the same during subsequent
receives of the fragments in a complete X.25 message
sequence. The D bit status for a complete X.25 message
sequence are returned before the recv() of the FINAL
fragment. The D bit status is also returned before the
recv() of a complete X.25 message sequence.
X25_WR_CAUSE_DIAG
Sets the cause code and diagnostic code for the next user-
initiated RESET or CLEAR packet. Cause and diagnostic codes
are set in the x25_cause_diag data structure defined in the
x25str.h header file. The cause code, if non-zero, will
Hewlett-Packard Company - 4 - HP-UX Release 9.0: August 1992
socketx25(7) socketx25(7)
Requires Optional LAN/X.25 Software
have its most significant byte set by the X.25 subsystem as
it appears in the X.25 packet. Set the cause and diagnostic
codes as follows:
struct x25_cause_diag diag;
int s; /* socket */
diag.x25_cd_cause = cause_code;
diag.x25_cd_diag = diagnostic_code;
error = ioctl(s, X25_WR_CAUSE_DIAG, &diag);
X25_CALL_ACPT_APPROVAL
Gives user the option to accept incoming calls on a listen
() socket. When the X25_CALL_ACPT_APPROVAL ioctl() call is
issued, a new accept() socket is created whenever a valid
call comes in, but the call is not accepted at the X.25
level until an X25_SEND_CALL_ACEPT ioctl() call is issued.
Until the X25_SEND_CALL_ACEPT ioctl() call is issued, no
data can be sent or received on the new socket. If the
application does not want to accept the call, the circuit
can be cleared with close(). Call acceptance cannot be
turned-off for a socket once the X25_CALL_ACPT_APPROVAL
ioctl() is issued. The call can be issued as follows:
error = ioctl(s, X25_CALL_ACPT_APPROVAL, 0);
where s is a listen socket; that is, a listen() system call
has been issued on it.
X25_SEND_CALL_ACEPT
Accepts a call on a new socket returned by accept() when the
listen socket has an X25_CALL_ACPT_APPROVAL ioctl() issued
against it; otherwise it is illegal. Once
X25_SEND_CALL_ACEPT is issued against a new socket, the
socket is in a data-transfer state. Accepting the new
socket is described below:
error = ioctl(new_s, X25_SEND_CALL_ACEPT, 0);
where new_s is the new socket created by accept().
X25_SETUP_PVC
Binds a socket to a Permanent Virtual Circuit (PVC). The
user must create a socket, then enter the X.25 interface
name and the PVC's Logical Channel Number (LCI) in the
x25_setup_pvc_str data structure defined in the
<x25/x25str.h> header file, before issuing the X25_SETUP_PVC
ioctl() call. This ioctl() call is the only call required
for setting-up a connection on a PVC; listen(), accept(),
and connect() are not required for establishing a connection
on a PVC. Once the ioctl() call completes successfully, the
Hewlett-Packard Company - 5 - HP-UX Release 9.0: August 1992
socketx25(7) socketx25(7)
Requires Optional LAN/X.25 Software
socket is in a connected state and data can be transmitted
over the connection. For example,
struct x25_setup_pvc_str pvc_str;
int pvc_so;
pvc_so = socket(AF_CCITT, SOCK_STREAM, 0);
/* Set the interface name in pvc_str.ifname.
* Store the LCI in pvc_str.lci. */
error = ioctl(pvc_so, X25_SETUP_PVC, &pvc_str);
X25_RD_USER_DATA
Reads data from the Call-user data field of a CALL
CONNECTED or INCOMING CALL packet, or reads the data field
of a CLEAR packet. Use the X25_NEXT_MSG_STAT ioctl() call
to determine that CALL or CLEAR data is available, then
issue the X25_RD_USER_DATA ioctl() call. The call transfers
user data to the x25_userdata data structure defined in
<x25str.h>, up to 126 bytes at a time. If more than 126
bytes of user data is available, the application should
loop, calling X25_NEXT_MSG_STAT and X25_RD_USER_DATA until
all the user data is read. This call is useful for fast-
select. The example below calls X25_NEXT_MSG_STAT to
determine whether CALL-user data available, then reads at
most 126 bytes of data.
struct x25_userdata userdata;
struct x25_msg_stat msgstat;
error = ioctl(s, X25_NEXT_MSG_STAT, &msgstat);
if (msgstat.x25_msg_flags & ( 1 << X25_CA_DATA_AVAIL))
error = ioctl(s, X25_RD_USER_DATA, &userdata);
X25_WR_USER_DATA
Writes to the Call-user data field in the following
situations:
o Before issuing a connect() call,
o Before issuing an accept() call when Call-accept
approval is in effect,
o Before issuing a close() call (which sends a CLEAR
packet over the connection); otherwise, it has no
effect.
If more than 16 bytes of Call and Clear data are written,
the fast-select facilities code must be set with the
X25_WR_FACILITIES ioctl() call. Only 126 bytes of Call and
Clear data can be written per ioctl() call. If the total
amount of user data is greater than 126 bytes,
X25_WR_USER_DATA returns with an EINVAL error. This example
copies CALL-user data from the array udata to the userdata
Hewlett-Packard Company - 6 - HP-UX Release 9.0: August 1992
socketx25(7) socketx25(7)
Requires Optional LAN/X.25 Software
structure, then writes the CALL-user data field:
struct x25_userdata userdata;
unsigned char udata[128];
int i, j = 0, ndata;
ndata = num_bytes_CALL_user_data;
while (ndata > 0) {
for (i = 0; ((ndata-- > 0) && ( i <= X25_MAX_CU_DATA)); i++)
userdata.x25_cu_data[i] = udata[j++];
userdata.x25_cud_len = i;
error = ioctl(s, X25_WR_USER_DATA, &userdata);
if (error)
break;
}
X25_RD_FACILITIES
Reads any inbound facilities data received with an INCOMING
CALL, CALL CONNECTED, CLEAR indication, or CLEAR confirm
packet. Facilities are defined in Section 7 of the CCITT
X.25 Recommendations. Facilities data cannot be reread, but
the X25_RD_FACILITIES ioctl () call can be issued again if
new facilities data is received. X25_RD_FACILITIES cannot
read outbound facilities data just written with the
X25_WR_FACILITIES ioctl () call.
X25_WR_FACILITIES
Sets up the facilities field. Facilities are defined in
Section 7 of the CCITT X.25 Recommendations. The network
provider might impose certain restrictions on facilities.
If no facilities are specified before initiating a call,
default flow-control facilities will be used. The
programmer should ensure that the facilities written contain
valid values and ranges as defined by the CCITT X.25
Recommendations and allowed by subscription by the network
provider. If a user issues the X25_WR_FACILITIES ioctl()
call with a field length of 0, no facilities are used for
that connection. This call overwrites any outbound
facilities data that hasn't been sent. Facilities data can
also be overwritten by receiving a CALL packet or a CLEAR
packet with a facilities field. The example below copies
faciliies data from the udata[] array to the facilities data
structure. Facilities data is stored in an x25_facilities
data structure defined in <x25/x25str.h>:
struct x25_facilities fac_data;
unsigned char udata[128];
int ndata;
/* ndata" counts the number"
*of bytes of facilities data.
* udata[] contains the facilities data.
*/
Hewlett-Packard Company - 7 - HP-UX Release 9.0: August 1992
socketx25(7) socketx25(7)
Requires Optional LAN/X.25 Software
memcpy(fac_data.x25_fac, udata, ndata);
fac_data.x25_fac_len = ndata;
error = ioctl(s, X25_WR_FACILITIES, &fac_data);
}
X25_RD_CTI
Returns the Circuit Table Index (CTI) associated with a
particular socket. Knowing the CTI enables the user to read
statistics and logging messages for a virtual circuit, as
well as examine the contents of a network log file such as
those created by netlogstat. The ioctl() call is issued as
follows:
int error, s, cti;
error = ioctl (s, X25_RD_CTI, &cti);
X25_RD_CTI returns an error if the
X25_RD_LCI
Returns the Logical Channel Index (LCI) associated with a
particular virtual circuit. Knowing the LCI enables the
user to relate logging messages to a protocol-analyzer
trace. The ioctl() call is issued as follows:
int error, s, lci; error = ioctl (s, X25_RD_LCI, &lci);
X25_RD_CTI returns an error if the circuit is not fully
connected.
X25_WR_WTHRESHOLD
Sets the write threshold for a socket. This call is used
with non-blocking I/O and select() calls. A socket is
considered write-selectable if there is enough outbound
buffer space for an X.25 message of the size specified with
X25_WR_WTHRESHOLD. Default: 1 byte. Range: 1 byte to
maximum send() message size specified with
setsockopt(SO_SNDBUF). The maximum outbound message size is
4096 bytes by default. Issue the X25_WR_WTHRESHOLD ioctl ()
call as follows:
int s, wthresh, error;
wthresh = 1024;
error = ioctl( s, X25_WR_WTHRESHOLD, &wthresh);
X25_WR_CALLING_SUBADDR
Specifies a calling subaddress field to be included in the
CALL REQUEST packet when initiating a connection request.
This ioctl() is useful for applications where a client
process initiates a virtual circuit and sends data to a
server process which then shuts down the circuit; the server
process manipulates the data, then reestablishes a virtual
Hewlett-Packard Company - 8 - HP-UX Release 9.0: August 1992
socketx25(7) socketx25(7)
Requires Optional LAN/X.25 Software
circuit with the same client (using a subaddress to identify
it). The X25_WR_CALLING_SUBADDR ioctl() call enables the
client to send addressing information to the server, which
the server can retain after a connection is shut down. The
addressing information is an X.121 sub-address. The
sequence of system calls for executing the above procedure
are summarized below:
1. The client loads X.121 sub-address information into an
x25addrstr struct. Only the address family,
subaddress, and size of subaddress fields in x25addrstr
are used:
#define SUBADDR = "12"
struct x25addrstr addrstr;
addrstr.x25_family = AF_CCITT;
addrstr.x25_hostlen = strlen(SUBADDR);
strncpy(addrstr.x25_host, SUBADDR, X25_MAXHOSTADDR);
2. The client binds to the address that the server will
"call back", then listens on that socket:
error = bind(s, &myaddr, sizeof(struct x25addrstr));
error = listen(s, 5);
3. The client issues the X25_WR_CALLING_SUBADDR ioctl()
call, with the subaddress information and all of the
other fields of the structure stored in addrstr, then
issues the connect() call:
error = ioctl(s, X25_WR_CALLING_SUBADDR, &addrstr);
error = connect(s, &to_addr, sizeof(struct x25addrstr));
4. The server receives the request, accepts the
connection, issues getpeername() on the calling socket
to obtain the addressing information, receives the
data, then clears the connection.
/* accept the connection request */
new_s = accept(s, &from_addr, &from_addr_len);
/* obtain addressing information for peer socket */
error = getpeername(new_s, &from_addr_info, sizeof(struct x25addrstr));
/* Clear the VC */
error = close(new_s);
For simplicity, no data exchanges between the client
and server are shown, but presumably there will be one
or more messages transmitted between them.
5. The server reestablishes a connection with the client
process (which has been listening on the socket s) by
Hewlett-Packard Company - 9 - HP-UX Release 9.0: August 1992
socketx25(7) socketx25(7)
Requires Optional LAN/X.25 Software
creating a call-back socket, then issuing a connect()
request using the subaddressing information and other
X.25 addressing information from the old socket.
call_back_s =
socket(AF_CCITT, SOCK_STREAM, X25_PROTO_NUM)
error = connect(call_back_s, &from_addr_info,
sizeof(struct x25addrstr));
X25_SET_FRAGMENT_SIZE
Sets fragment size for reception of an X.25 message in
fragments. Normally, X.25/9000 software sends data to the
user in complete X.25 message sequences. If it is desired
to receive X.25 normal data in fragments of the complete
X.25 sequences, the X25_SET_FRAGMENT_SIZE I/O Control (see
ioctl(2)) call must be used. This ioctl() informs the
X.25/9000 software that inbound X.25 normal data should be
sent to the user when the reassembled data size is equal to
or greater than the size specified in the
X25_SET_FRAGMENT_SIZE ioctl(). When the end of a complete
X.25 message sequence is encountered, the remaining data is
sent to the user.
The X25_SET_FRAGMENT_SIZE ioctl() can be used to set inbound
fragment sizes up to 32767 bytes (32K). Values greater than
32K cause the ioctl() to return with an error indicating
that the fragment size is too large, and the operation will
be ignored. To return to receiving complete X.25 message
sequences, set fragment_size to zero (0).
The semantics of the X25_SET_FRAGMENT_SIZE ioctl() is shown
below:
int socket, fragment_size;
extern int errno;
error=ioctl(socket, X25_SET_FRAGMENT_SIZE,
&fragment_size);
if ((error == -1) && (errno == EMSGSIZE)) {
printf( fragment_size too big0);"
}
if ((error == -1) && (errno == ENOTCONN)) {
printf( circuit not connected0);"
}
The received fragment may be slightly larger than the
fragment_size specified in the X25_SET_FRAGMENT_SIZE
ioctl(). This is due to some inbound data reassembly being
performed on the X.25 interface. It is highly recommended
that the X25_NEXT_MSG_STAT ioctl() be used to determine the
Hewlett-Packard Company - 10 - HP-UX Release 9.0: August 1992
socketx25(7) socketx25(7)
Requires Optional LAN/X.25 Software
size of the message before it is received.
The received fragment may also be smaller than the
fragment_size specified in the X25_SET_FRAGMENT_SIZE
ioctl(). This is due to the detection of the end of a
complete X.25 message sequence.
The X25_SET_FRAGMENT_SIZE ioctl() can be used only when the
circuit is connected. It can be used at any time during the
life of the circuit.
Inbound and outbound socket buffers should be set to at
least the fragment size plus 4K (4096). This ensures that
the proper amount of memory is reserved for operation of the
virtual circuit. The default socket buffer size is 4K (4096
bytes).
DEPENDENCIES
Series 300/400 X.25:
Series 300/400 systems do not support setting the D-bit
programmatically.
AUTHOR
socketx25 was developed by HP.
FILES
<x25/x25ioctls.h>
<x25/x25str.h>
<x25/x25addrstr.h>
<x25/x25com.h>
SEE ALSO
getsockopt(2), ioctl(2), socket(2), socket(7),
CCITT Data Communication Network Interfaces Recommendation X.25 ,
X.25 Programmer's Manual.
Hewlett-Packard Company - 11 - HP-UX Release 9.0: August 1992