Previous section.

Technical Standard: Networking Services (XNS), Issue 5.2 Draft 2.0
Copyright © 1999 The Open Group

Use of XTI to Access NetBIOS

Introduction

NetBIOS represents an important de facto standard for networking DOS and OS/2 PCs. The X/Open Specification Protocols for X/Open PC Interworking: SMB (see the referenced NetBIOS specification) provides mappings of NetBIOS services to OSI and IPS transport protocols1.

XTI defines a transport service interface that is independent of any specific transport provider.

This Appendix defines a standard for using XTI to access NetBIOS transport providers. Applications that use XTI to access NetBIOS transport providers are referred to as "transport users".

This Appendix also defines data structures and constants required for NetBIOS transport providers which are exposed through <xti_netbios.h> header file.

Note:
Applications written to compilation environments earlier than those required by this issue of the specification (see The Compilation Environment) and defining _XOPEN_SOURCE to be less than 500, may have these data structures and constants exposed through the inclusion of <xti.h>

Objectives

The objectives of this standardisation are:

  1. to facilitate the development and portability of applications that interwork with the large installed base of NetBIOS applications in a Local Area Network (LAN) environment

  2. to enable a single application to use the same XTI interface to communicate with remote applications through either an IPS profile, an OSI profile or a NetBIOS profile (that is, RFC 1001/1002 or TOP/NetBIOS)

  3. to provide a common interface that can be used for IPC with clients using either (PC)NFS or SMB protocols for resources sharing.

This Appendix provides a migration step to users moving from proprietary systems in a NetBIOS environment an "open systems" environment.

Scope

No extensions are made to XTI by the definitions provided in this Appendix. This NetBIOS specification is concerned only with standardisation of the mapping of XTI to the NetBIOS facilities, and not a new definition of XTI itself.

This NetBIOS specification applies only to the use of XTI in the single NetBIOS subnetwork case, and does not provide for the support of applications operating in multiple, non-overlapping NetBIOS name spaces.

The following NetBIOS facilities found in various NetBIOS implementations are considered outside the scope of XTI (note that this list is not necessarily definitive):

It must also be noted that not all commands are specified in the protocols.

Omitting these does not restrict interoperability with the majority of NetBIOS implementations, since they have local significance only (RESET, SESSION STATUS), are concerned with systems management (UNLINK, RPL, ADAPTER STATUS), or are LAN- and vendor-specific (FIND NAME). If and how these functions are made available to the programmer is left to the implementor of this particular XTI implementation.

Issues

The primary issues for XTI as a transport interface to NetBIOS concern the passing of NetBIOS names and name type information through XTI, specification of restrictions on XTI functions in the NetBIOS environment, and handling the highly dynamic assignment of NetBIOS names.

NetBIOS Names and Addresses

NetBIOS uses 16-octet alphanumeric names as "transport" addresses. NetBIOS names must be exactly 16 octets, with shorter names padded with spaces to 16 octets. In addition, NetBIOS names are either unique names, group names or local names, and must be identified as such in certain circumstances. A local NetBIOS name is a name that is not defended on the network.

The following restrictions should be applied to NetBIOS names. Failure to observe these restrictions may result in unpredictable results.

  1. Byte 0 of the name is not allowed to be hexadecimal 00 (0x00).

  2. Byte 0 of the name is not allowed to be an asterisk, except as noted elsewhere in this specification to support broadcast datagrams.

  3. Names should not begin with company names or trademarks.

  4. Names should not begin with hexadecimal FF (0xFF).

  5. Byte 15 of the name should not be in the range 0x00 - 0x1F.

The concept of a permanent node name, as provided in the native NetBIOS environment, is not supported in The Open Group's concept of an "open system".

The following definitions are supplied with any implementation of XTI on top of NetBIOS. These definitions are exposed by the inclusion of <xti_netbios.h>.


#define T_NB_UNIQUE        0
#define T_NB_GROUP         1
#define T_NB_LOCAL         2
#define T_NB_NAMELEN      16
#define T_NB_BCAST_NAME    "*     "    /* asterisk plus 15 spaces */


The protocol addresses passed in calls to t_bind(), t_connect(), etc., are structured as follows:


1 2 17 +----+-------------------------------+ |Type| NetBIOS Name | +----+-------------------------------+

Type
The first octet specifies the type of the NetBIOS name. It may be set to T_NB_UNIQUE, T_NB_GROUP or T_NB_LOCAL.

NetBIOS Name
Octets 2 through 17 contain the 16-octet NetBIOS name.

All NetBIOS names, complete with the name type identifier, are passed through XTI in a netbuf address structure (that is, struct netbuf addr), where addr.buf points to a NetBIOS protocol address as defined above. This applies to all XTI functions that pass or return a (NetBIOS) protocol address (for example, t_bind(), t_connect(), t_rcvudata(), etc.).

Note, however, that only the t_bind() and t_getprotaddr() functions use the name type information. All other functions ignore it.

If the NetBIOS protocol address is returned, the name type information is to be ignored since the NetBIOS transport providers do not provide the type information in the connection establishment phase.

NetBIOS names can become invalid even after they have been registered successfully due to the NetBIOS name conflict resolution process (for example, Top/NetBIOS NameConflictAdvise indication). For existing NetBIOS connections this has no effect since the connection endpoint can still be identified by the fd. However, in the connection establishment phase 2t_listen() and t_connect()) this event is indicated by setting t_errno to [TBADF].

NetBIOS Connection Release

Native NetBIOS implementations provide a linger-on-close release mechanism whereby a transport disconnection request (NetBIOS HANGUP) will not complete until all outstanding send commands have completed. NetBIOS attempts to deliver all queued data by delaying, if necessary, disconnection for a period of time. The period of time might be configurable; a value of 20 seconds is common practice. Data still queued after this time period may get discarded so that delivery cannot be guaranteed.

XTI, however, offers two different modes to release a connection: an abortive mode via /.Fn/.Fn()t_rcvdis and a graceful mode via /.Fn/.Fn()t_rcvrel If a connection release is initiated by a t_snddis(), queued send data may be discarded. Only the use of t_sndrel() guarantees that the linger-on-close mechanism is enabled as described above. The support of /.Fn/.Fn()t_rcvrel is optional and only provided by implementations with servtype T_COTS_ORD (see t_getinfo() in XTI Functions).

A call to t_sndrel() initiates the linger-on-close mechanism and immediately returns with the XTI state changed to T_OUTREL. The NetBIOS provider sends all outstanding data followed by a NetBIOS Close Request. After receipt of a NetBIOS Close Response, the NetBIOS provider informs the transport user, via the event T_ORDREL, that is to be consumed by calling t_rcvrel(). If a timeout occurs, however, a T_DISCONNECT event with a corresponding reason code is generated.

Receive data arriving before the NetBIOS Close Request is sent is indicated by T_DATA and can be read by the transport user.

Calling t_snddis() initiates an abortive connection release and immediately returns with the XTI state changed to T_IDLE. Outstanding send and receive data may be discarded. The NetBIOS provider sends as many outstanding data as possible prior to closing the connection, but discards any receive data. Some outstanding data may be discarded by the t_snddis() mechanism, so that not all data can be sent by the NetBIOS provider. Furthermore, an occurring timeout condition could not be indicated to the transport user.

An incoming connection release will always result in a T_DISCONNECT event, never in a T_ORDREL event. To be precise, if the NetBIOS provider receives a Close Request, it discards any pending send and receive data, sends a Close Response and informs the transport user via T_DISCONNECT.

Options

No NetBIOS-specific options are defined. An implementation may, however, provide XTI-level options (see t_optmgmt.

XTI Functions

t_accept()
No user data may be returned to the caller (call->udata.len=0).

This function may only be used with connection-mode transport endpoints. The t_accept() function will fail if a user attempts to accept a connection request on a connectionless-mode endpoint and t_errno will be set to [TNOTSUPPORT].

t_alloc()
No special considerations for NetBIOS transport providers.

t_bind()
The NetBIOS name and name type values are passed to the transport provider in the req parameter (req->addr.buf) and the actual bound address is returned in the ret parameter (ret->addr.buf), as described earlier in NetBIOS Names and Addresses. If the NetBIOS transport provider is unable to register the name specified in the req parameter, the call to t_bind() will fail with t_errno set to [TADDRBUSY] if the name is already in use, or to [TBADADDR] if it was an illegal NetBIOS name. If the NetBIOS name type is T_NB_LOCAL the name is not defended on the network, that is, it is not registered.

If the req parameter is a null pointer or req->addr.len=0, the transport provider may assign an address for the user. This may be useful for outgoing connections on which the name of the caller is not important.

If the name specified in req parameter is T_NB_BCAST_NAME, qlen must be zero, and the transport endpoint the name is bound to is enabled to receive broadcast datagrams. In this case, the transport endpoint must support connectionless-mode service, otherwise the t_bind() function will fail and t_errno will be set to [TBADADDR].

t_close()
No special considerations for NetBIOS transport providers.

It is assumed that the NetBIOS transport provider will release the NetBIOS name associated with the closed endpoint if this is the only endpoint bound to this name and the name has not already been released as the result of a previous t_unbind() call on this endpoint.

t_connect()
The NetBIOS name of the destination transport user is provided in the sndcall parameter (sndcall->addr.buf), and the NetBIOS name of the responding transport user is returned in the rcvcall parameter (rcvcall->addr.buf), as described in NetBIOS Names and Addresses. If the connection is successful, the NetBIOS name of the responding transport user will always be the same as that specified in the sndcall parameter.

Local NetBIOS connections are supported. NetBIOS datagrams are sent, if applicable, to local names as well as remote names. No user data may be sent during connection establishment (udata.len=0 in sndcall).

This function may only be used with connection-mode transport endpoints. The t_connect() function will fail if a user attempts to initiate a connection on a connectionless-mode endpoint and t_errno will be set to [TNOTSUPPORT].

[TBADF] may be returned in the case that the NetBIOS name associated with the fd referenced in the t_connect() call is no longer in the system name table (see NetBIOS Names and Addresses.

t_error()
No special considerations for NetBIOS transport providers.

t_free()
No special considerations for NetBIOS transport providers.

t_getinfo()
The values of the parameters in the t_info structure will reflect NetBIOS transport limitations, as follows:

addr
sizeof() the NetBIOS protocol address, as defined in NetBIOS Names and Addresses.

options
Equals -2, indicating no user-settable options.

tsdu
Equals the size returned by the transport provider. If the fd is associated with a connection-mode endpoint it is a positive value, not larger than 131070. If the fd is associated with a connectionless-mode endpoint it is a positive value not larger than 655352.

etsdu
Equals -2, indicating expedited data is not supported.

connect
Equals -2, indicating data cannot be transferred during connection establishment.

discon
Equals -2, indicating data cannot be transferred during connection release.

servtype
Set to T_COTS if the fd is associated with a connection-mode endpoint, or T_CLTS if associated with a connectionless-mode endpoint. Optionally, may be set to T_COTS_ORD if the fd is associated with a connection-mode endpoint and the transport provider supports the use of /.Fn/.Fn()t_rcvrel as described in NetBIOS Connection Release.

flags
Equals T_SNDZERO, indicating that zero TSDUs may be sent.

t_getprotaddr()
The NetBIOS name and name type of the transport endpoint referred to by the fd are passed in the boundaddr parameter (boundaddr->addr.buf), as described in NetBIOS Names and Addresses; 0 is returned in boundaddr->addr.len if the transport endpoint is in the T_UNBND state. The NetBIOS name currently connected to fd, if any, is passed in the peeraddr parameter (peeraddr->addr.buf); the value 0 is returned in peeraddr->addr.len if the transport endpoint is not in the T_DATAXFER state.

t_getstate()
No special considerations for NetBIOS transport providers.

t_listen()
On return, the call parameter provides the NetBIOS name of the calling transport user (that issued the connection request), as described in NetBIOS Names and Addresses.

No user data may be transferred during connection establishment (call->udata.len=0 on return).

This function may only be used with connection-mode transport endpoints. The t_listen() function will fail if a user attempts to listen on a connectionless-mode endpoint and t_errno will be set to [TNOTSUPPORT]. [TBADF] may be returned in the case that the NetBIOS name associated with the fd referenced in the t_listen() function is no longer in the system name table, as may occur as a result of the NetBIOS name conflict resolution process (for example, TOP/NetBIOS NameConflictAdvise indication).

t_look()
Since expedited data is not supported in NetBIOS, the T_EXDATA and T_GOEXDATA events cannot be returned.

t_open()
No special considerations for NetBIOS transport providers, other than restrictions on the values returned in the t_info structure. These restrictions are described in t_getinfo.

t_optmgmt()
No special considerations for NetBIOS transport providers.

t_rcv()
This function may only be used with connection-mode transport endpoints. The t_rcv() function will fail if a user attempts a receive on a connectionless-mode endpoint and t_errno will be set to [TNOTSUPPORT].

The flags parameter will never be set to T_EXPEDITED, as expedited data is not supported.

Data transfer in the NetBIOS environment is record-oriented, and the transport user should expect to see usage of the T_MORE flag when the message size exceeds the available buffer size.

t_rcvconnect()
The NetBIOS name of the transport user responding to the previous connection request is provided in the call parameter (call->addr.buf), as described in NetBIOS Names and Addresses.

No user data may be returned to the caller (call->udata.len=0 on return).

This function may only be used with connection-mode transport endpoints. The t_rcvconnect() function will fail if a user attempts to establish a connection on a connectionless-mode endpoint and t_errno will be set to [TNOTSUPPORT].

t_rcvdis()
The following disconnection reason codes are valid for any implementation of a NetBIOS provider under XTI:

#define T_NB_ABORT 0x18 /* session ended abnormally */ #define T_NB_CLOSED 0x0A /* session closed */ #define T_NB_NOANSWER 0x14 /* no answer (cannot find */ /* name called */ #define T_NB_OPREJ 0x12 /* session open rejected */

These definitions are exposed by the inclusion of <xti_netbios.h>.

t_rcvrel()
As described in NetBIOS Connection Release, a T_ORDREL event will never occur in the T_DATAXFER state, but only in the T_OUTREL state. A transport user thus has only to prepare for a call to t_rcvrel() if it previously initiated a connection release by calling t_sndrel(). As a side effect, the state T_INREL is unreachable for the transport user.

If T_COTS_ORD is not supported by the underlying NetBIOS transport provider, this function will fail with t_errno set to [TNOTSUPPORT].

t_rcvudata()
The NetBIOS name of the sending transport user is provided in the unitdata parameter (unitdata->addr.buf), as described in NetBIOS Names and Addresses.

The fd associated with the t_rcvudata() function must refer to a connectionless-mode transport endpoint. The function will fail if a user attempts to receive on a connection-mode endpoint and t_errno will be set to [TNOTSUPPORT]. [TBADF] may be returned in the case that the NetBIOS name associated with the fd referenced in the t_rcvudata() function is no longer in the system name table, as may occur as a result of the NetBIOS name conflict resolution process (for example, TOP/NetBIOS NameConflictAdvise indication).

To receive a broadcast datagram, the endpoint must be bound to the NetBIOS name T_NB_BCAST_NAME.

t_rcvuderr()
If attempted on a connectionless-mode transport endpoint, this function will fail with t_errno set to [TNOUDERR], as no NetBIOS unit data error codes are defined. If attempted on a connection-mode transport endpoint, this function will fail with t_errno set to [TNOTSUPPORT].

t_snd()
The T_EXPEDITED flag may not be set, as NetBIOS does not support expedited data transfer.

This function may only be used with connection-mode transport endpoints. The t_snd() function will fail if a user attempts a send on a connectionless-mode endpoint and t_errno will be set to [TNOTSUPPORT].

The maximum value of the nbytes parameter is determined by the maximum TSDU size allowed by the transport provider. The maximum TSDU size can be obtained from the t_getinfo() call.

Data transfer in the NetBIOS environment is record-oriented. The transport user can use the T_MORE flag in order to fragment a TSDU and send it via multiple calls to t_snd(). See t_snd for more details.

NetBIOS does not support the notion of expedited data. A call to t_snd() with the T_EXPEDITED flag will fail with t_errno set to [TBADDATA].

If the NetBIOS provider has received a HANGUP request from the remote user and still has receive data to deliver to the local user, XTI may not detect the HANGUP situation during a call to t_snd(). The actions that are taken are implementation-dependent:

t_snddis()
The t_snddis() function initiates an abortive connection release. The function returns immediately. Outstanding send and receive data may be discarded. See NetBIOS Connection Release for further details.

No user data may be sent in the disconnection request (call->udata.len=0).

This function may only be used with connection-mode transport endpoints. The t_snddis() function will fail if a user attempts a disconnection request on a connectionless-mode endpoint and t_errno will be set to [TNOTSUPPORT].

t_sndrel()
The t_sndrel() function initiates the NetBIOS release mechanism that attempts to complete outstanding sends within a timeout period before the connection is released. The function returns immediately. The transport user is informed by T_ORDREL when all sends have been completed and the connection has been closed successfully. If, however, the timeout occurs, the transport user is informed by a T_DISCONNECT event with an appropriate disconnection reason code. See NetBIOS Connection Release for further details.

If the NetBIOS transport provider did not return T_COTS_ORD with t_open(), this function will fail with t_errno set to [TNOTSUPPORT].

t_sndudata()
The NetBIOS name of the destination transport user is provided in the unitdata parameter (unitdata->addr.buf), as described in NetBIOS Names and Addresses.

The fd associated with the t_sndudata() function must refer to a connectionless-mode transport endpoint. The function will fail if a user attempts this function on a connection-mode endpoint and t_errno will be set to [TNOTSUPPORT]. [TBADF] may be returned in the case that the NetBIOS name associated with the fd referenced in the t_sndudata() function is no longer in the system name table, as may occur as a result of the NetBIOS name conflict resolution process (for example, TOP/NetBIOS NameConflictAdvise indication).

To send a broadcast datagram, the NetBIOS name in the NetBIOS address structure provided in unitdata->addr.buf must be T_NB_BCAST_NAME.

t_strerror()
No special considerations for NetBIOS transport providers.

t_sync()
No special considerations for NetBIOS transport providers.

t_unbind()
No special considerations for NetBIOS transport providers.

It is assumed that the NetBIOS transport provider will release the NetBIOS name associated with the endpoint if this is the only endpoint bound to this name.

Compatibility.

Certain symbols may be exposed to applications including <xti_netbios.h> for compatibility with applications transitioning from older issues of this specification where their semantics are specified. Exposing these symbols is allowed but not required. Symbols that may be exposed in this implementation-dependent manner are:

NB_UNIQUE, NB_GROUP, NB_LOCAL, NB_NAMELEN, NB_BCAST_NAME NB_ABORT, NB_CLOSED, NB_NOANSWER, NB_OPREJ


Footnotes

1.
The mappings are defined by the Specification of NetBIOS Interface and Name Service Support by Lower Layer OSI Protocols, and RFC 1001/RFC 1002 respectively. See the referenced NetBIOS specification. The relevant chapters are Chapter 13, NetBIOS Interface to ISO Transport Services, Chapter 14, Protocol Standard for a NetBIOS Service on a TCP/UDP Transport: Concepts and Methods and Chapter 15, Protocol Standard for a NetBIOS Service on a TCP/UDP Transport: Detailed Specification.

2.
For the mappings to OSI and IPS protocols, the value cannot exceed 512 or 1064 respectively.

Contents Next section Index