Previous section.
Networking Services (XNS) Issue 5
Copyright © 1997 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.
The following CAE Specification extends that work
to provide a standard
programming interface to NetBIOS transport providers in X/Open-compliant
systems, using an existing X/Open Common Applications Environment (CAE)
interface, XTI.
The X/Open Transport Interface (XTI) defines
a transport service interface that is independent of any specific transport
provider.
This CAE Specification 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.
Applications written to compilation environments earlier than
those required by this issue of the specification (see
Headers and Definitions for XTI
)
and defining _XOPEN_SOURCE to be less than 500, will have these
data structures and constants exposed through the inclusion of
<xti.h>
on platforms where XTI interface use is supported for NetBIOS transports.
Objectives
The objectives of this standardisation are:
-
to facilitate the development and
portability of CAE applications that interwork with the large installed
base of NetBIOS applications in a Local Area Network (LAN) environment
-
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)
-
to provide a common interface that can be used for IPC with clients
using either (PC)NFS or SMB protocols for resources sharing.
This CAE Specification provides a migration step
to users moving from proprietary
systems in a NetBIOS environment to open systems, that is, the X/Open CAE.
Scope
No extensions to XTI, as it is defined in the main body bgcolor="#FFFFFF" of this
CAE Specification, are made in this NetBIOS CAE Specification.
This NetBIOS CAE Specification is concerned only with
standardisation of the mapping of XTI to the NetBIOS facilities,
and not a new definition of XTI itself.
This CAE 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):
-
LAN.STATUS.ALERT
-
RESET
-
SESSION STATUS
-
TRACE
-
UNLINK
-
RPL (Remote Program Load)
-
ADAPTER STATUS
-
FIND NAME
-
SEND.NOACK
-
CHAIN.SEND.NOACK
-
CANCEL
-
receiving a datagram on any name
-
receiving data on any connection.
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.
-
Byte 0 of the name is not allowed to be hexadecimal 00 (0x00).
-
Byte 0 of the name is not allowed to be an asterisk, except as noted
elsewhere in this specification to support broadcast datagrams.
-
Names should not begin with company names or trademarks.
-
Names should not begin with hexadecimal FF (0xFF).
-
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 X/Open CAE.
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 NB_UNIQUE 0 (LEGACY)
#define T_NB_GROUP 1
#define NB_GROUP 1 (LEGACY)
#define T_NB_LOCAL 2
#define NB_LOCAL 2 (LEGACY)
#define T_NB_NAMELEN 16
#define NB_NAMELEN 16 (LEGACY)
#define T_NB_BCAST_NAME "* " /* asterisk plus 15 spaces */
#define NB_BCAST_NAME "* " (LEGACY)
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 CAE 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 CAE 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 NB_ABORT 0x18 /* (
LEGACY) */
#define T_NB_CLOSED 0x0A /* session closed */
#define NB_CLOSED 0x0A /* (LEGACY) */
#define T_NB_NOANSWER 0x14 /* no answer (cannot find */
/* name called */
#define NB_NOANSWER 0x14 /* (LEGACY) */
#define T_NB_OPREJ 0x12 /* session open rejected */
#define NB_OPREJ 0x12 /* (LEGACY) */
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 CAE 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_snd()
might fail with t_errno set to [TPROTO]
-
t_snd()
might succeed, although the data is discarded by the transport
provider, and an implementation-dependent error (generated by the NetBIOS
provider) will result on a subsequent XTI call.
This could be a [TSYSERR],
a [TPROTO] or a connection release indication after all the receive data
has been delivered.
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 CAE 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.
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.
Why not acquire a nicely bound hard copy?
Click here to return to the publication details or order a copy
of this publication.