Programming NetBIOS on OS/2

Recently I spent some time trying to understand a piece of networking code, and it turned out to be far more difficult than it should have been. The code in question is the NetBIOS interface of C-Kermit and was originally written in the early 1990s.

The module uses two very similar but not identical code paths. The comments suggest that one alternative, using ACSNETB.DLL, is the “Traditional NetBios interface” used by IBM’s LAN Adapter and Protocol Support (aka LAPS), OS/2 Extended Services, and Communications Manager/2. The other code path uses NETAPI.DLL and it’s called “Newer Netbeui Interface”, used by the Microsoft LAN Manager Requester, IBM LAN Server Requester, and Novell Netware Requester. The comments are wrong, but more about that below.

The API used by NETAPI.DLL is documented in the Microsoft LAN Manager programming reference. It consists of four functions: NetBiosEnum, NetBiosOpen, NetBiosSubmit, and NetBiosClose. The NetBiosSubmit function takes an NCB (Network Control Block) as input, except the NCB usage is left more or less completely undocumented by Microsoft.

The LAN Manager document points programmers curious about NCBs to the “IBM PC-NET Technical Reference”, “IBM PC LAN Technical Reference”, and “IBM PC-LAN Technical Reference”, all in the same Microsoft manual. (Which is exactly why IBMers considered Microsoft sloppy and undisciplined.)

My initial search for programming the ACSNETB.DLL interface turned up nothing. I could not find anything in the Communications Manager manuals, or in the MPTS documentation, or really anywhere one would normally find OS/2 programming information. Because it’s not there.

Documentation

But this is IBM we’re talking about, so of course it is documented, and quite extensively. As far as I can establish, the ACSNETB.DLL interface was first documented in the IBM Local Area Network Technical Reference, document SC30-3383-2, published in November 1988 (around the same time OS/2 1.1 Extended Edition was released).

The 1988 LAN Tech Ref documents the IBM Token-Ring adapter register interface, as well as IEEE 802.2 and NetBIOS programming interfaces for DOS and OS/2. That may seem like a strange combination, but it is not an accident. OS/2 1.1 Extended Edition implemented what IBM called NetBIOS 3.0.

The NetBIOS programming interface (for DOS, but really it was for real mode 8086) was originally documented in IBM’s 1984 PC Network Technical Reference, document 6322916. The PC Network Tech Ref documented the programming interface of the PC Network adapter, which was none other than NETBIOS (literally the ROM BIOS of the PC Network adapter).

When IBM rolled out Token-Ring, NetBIOS continued to be the an important programming interface, but IBM also added a lower-level IEEE 802.2 DLC programming interface. There was a new Token-Ring PC Adapter Technical Reference, document 69X7862 (that’s the second edition from June 1986).

The above mentioned 1988 LAN Tech Ref is in fact the second edition of the Token-Ring PC Adapter Technical Reference, and it covers OS/2 (specifically OS/2 Extended Edition 1.1) in addition to DOS/BIOS.

In 1993, IBM did what they arguably should have done a long time ago: The LAN Technical Reference was split into hardware-specific and more general programming documents:

  • Publication SC30-3587, IEEE 802.2 and NETBIOS Application Program Interfaces
  • Publication SC30-3588, Token-Ring Network Adapter Interface
  • Publication SC30-3661, Ethernet Adapter Interface
  • Publication SC30-3663, Token-Ring Network 16/4 Busmaster Server Adapter/A Interface

In December 1993, IBM published the first edition of the IEEE 802.2 and NETBIOS APIs as SC30-3587-00. This publication documented the NetBIOS 4.0 interface, supported as part of IBM LAPS (LAN Adapter Protocol Support).

The final edition of NetBIOS programming reference appeared in May 1996 as publication SC30-3587-01 and is available in IBM BookManager format here.

As a side note, the first edition of SC30-3587 was titled IEEE 802.2 and NETBIOS APIs while the second was IEEE 802.2 and NetBIOS APIs—note the change in capitalization.

ACSNETB.DLL

The 1988 LAN Tech Ref (SC30-3383-2) defined two NetBIOS programming interfaces: One available to OS/2 device drivers and the other to applications. These interfaces are quite similar.

ACSNETB.DLL is a relatively thin wrapper around the NETBIOS$ device driver. It uses IOCTLs to communicate with the NetBIOS driver, and it also creates a thread used to dispatch optional NCB completion routines (stored in the NCB_POST@ field of an NCB).

As one might expect, ACSNETB.DLL first appeared in OS/2 Extended Edition 1.1 in late 1988, as part of the Communications Manager component. ACS was the designation of the Communications Manager core. Perhaps ACS stood for Advanced Communication Services or similar?

At that time, OS/2 NetBIOS drivers were monolithic, a single .SYS driver which interfaced with networking hardware and provided a NetBIOS programming interface. The architecture was later reworked using NDIS, with much simpler hardware specific drivers and a generic NetBIOS implementation on top.

The ACSNETB.DLL interface has no real dependencies other than a functioning NetBIOS driver. It does not require any higher level networking software.

NETAPI.DLL

The NETAPI.DLL interface is rather more involved. Instead of talking directly to a NetBIOS driver, it uses a private interface to the LAN Manager/LAN Requester redirector IFS (obviously the internal interface was slightly different in times of OS/2 1.1, before IFSs existed).

To complicate matters, Novell shipped its own NETAPI.DLL implementation with the OS/2 Requester. Novell’s variant was very stripped down as its primary purpose was to support the NetBIOS programming interface, in a manner compatible with MS LAN Manager and IBM LAN Requester.

Novell soon found out that products like SQL Server use NETAPI.DLL for a bit more than just NetBIOS, and that replacing the entire NETAPI.DLL is not so simple. Newer versions of NETAPI.DLL have a built-in switch: if the network redirector interface is operational, the redirector file system interface is used for routing NetBIOS calls. But if it’s not, NETAPI.DLL attempts to dynamically load NETSUB.DLL, and effectively passes through NetBiosSubmit and associated APIs to the external NETSUB module. As far as I can establish, only Novell shipped NETSUB.DLL.

For whatever reason, while IBM’s ACSNETB.DLL interface can use a completion callback specified in the NCB_POST@ field (just like the real mode NETBIOS interface), Microsoft’s NETAPI.DLL instead uses a system semaphore. Rather than calling a user specified routine, NETAPI.DLL clears a semaphore specified in NCB_POST@ when the NCB is completed.

Combinations

It is notable that OS/2 Extended Edition 1.1 also shipped NETAPI.DLL (not just ACSNETB.DLL), but this was part of the LAN Requester component, not Communications Manager. And just to complete the circle, at least LAN Manager 2.1 shipped ACSNETB.DLL in addition to NETAPI.DLL.

Needless to say, there were various combinations in the field, and it is clear why C-Kermit felt compelled to support both the ACSNETB.DLL and the NETAPI.DLL interfaces.

In the late 1980s, users of LAN Manager or the Novell Requester had NETAPI.DLL but not ACSNETB.DLL. OS/2 Extended Edition users had ACSNETB.DLL and might also have NETAPI.DLL installed, but not necessarily so.

In the OS/2 2.0 days, users who installed LAPS had ACSNETB.DLL, but did not have NETAPI.DLL unless they also had the LAN Requester installed. On the other hand, NetWare users might have NETAPI.DLL but no ACSNETB.DLL.

Starting with Warp Connect, both ACSNETB.DLL and NETAPI.DLL were shipped with the OS, and users who installed the file and print sharing component (i.e. LAN Requester) had both. But even then, it was possible to end up with only one of ACSNETB.DLL or NETAPI.DLL.

But Why Oh Why?

The reason for this schizophrenic NetBIOS API was IBM and Microsoft’s schizophrenic approach to networking in the OS/2 1.x days.

If you wanted networking for IBM OS/2, you needed the Extended Edition (EE). Which initially only supported IBM networking hardware. While OS/2 EE came with the LAN Requester, that was an optional component, and the Communications Manager supported a whole host of IBM networking protocols (including NetBIOS) that were in no way tied to LAN Manager style file sharing.

If you wanted networking for MS OS/2, you needed LAN Manager… which was not available from Microsoft but only through OEMs (like MS OS/2 itself). And Microsoft only provided the “top half” of LAN Manager, while the OEM had to supply the “bottom half” which included hardware drivers and at least part of the NetBIOS protocol implementation.

And last but not least, if you wanted NetWare support for either IBM or MS OS/2, you needed the OS/2 Requester from Novell.

Both the ACSNETB.DLL and NETAPI.DLL interfaces were available in OS/2 Extended Edition 1.1 in late 1988. There is no evidence that one API is older than the other. On the contrary, there is every reason to believe that they were defined more or less at the same time, but reflected different networking strategies and requirements of IBM vs Microsoft.

Due to the vagaries of IBM’s networking support, it was common to have both ACSNETB.DLL and NETAPI.DLL on a networked OS/2 machine. But applications wishing to support all possible scenarios needed to support both, because any given system might have only one or the other interface available.

Whichever interface is used, ACSNETB.DLL or NETAPI.DLL, the IBM Local Area Network Technical Reference or the later IEEE 802.2 and NetBIOS Application Program Interfaces is the reference which documents actual NetBIOS programming.

This entry was posted in Development, Documentation, IBM, Microsoft, Novell, OS/2. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.