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.

10 Responses to Programming NetBIOS on OS/2

  1. Fernando says:

    I’m not sure if this has something to do with this, but the redbook “Network Clients for OS/2 Warp Server: OS/2 Warp 4 DOS/Windows, Windows 95/NT, and Apple Macintosh” – August 1997 has this paragraph:
    “NetBEUI is the original PC networking protocol and interface designed by IBM for their OS/2 LAN Server/OS/2 Warp Server. This protocol was later adopted by Microsoft for their networking products. Many of the performance enhancements came from Microsoft.”
    P.S. Your previous post sent me in a rabbit hole of versions of NetBIOS, NetBEUI, SMB, CIFS.
    One SAMBA maintainer wishing that the protocol already die.

  2. MiaM says:

    Interesting!

    Looking at the kermit 95 web page, it seems like it supports NetBIOS only on OS/2. I wonder what use case they saw in that?
    http://www.columbia.edu/kermit/k95.html

    It seems like the first OS/2 Kermit was released in 1995, which is somewhat late as compared to what’s mentioned above, but might had targeted existing installations using older versions of OS/2?
    http://www.columbia.edu/kermit/cko191.html

    I wonder how much (and/or little) work it would be to port the NetBIOS part over to Windows. Maybe that’s what you are working on? 🙂

    Although there wouldn’t be any use case for it, it would probably not be that hard to add support for terminal connections over NetBIOS in Samba. That way Kermit 95 on OS/2 could use NetBIOS over TCP/IP to connect to a Samba server to get a login shell on a Linux computer 🙂

    I don’t think that Samba on Linux supports NetBIOS over DECNET – that would otherwise be a fabulous type of cursed networking to use Kermit on top of 🙂

    I assume that it would be harder to port the NetBIOS client code from Kermit 95 to the DOS version of Kermit? Would otherwise be a cool thing, although not really useful. If anyone takes on this, they could perhaps also have a go at the DECnet for DOS / Pathworks for DOS API:s to use Kermit over LAT and/or CTERM (unless that’s already a thing). 🙂

    As a complete side track: When I saw you mention callback v.s. semaphore, I came to wonder if the different choices in “reply API” implementations were affected by having experience with different types of hardware? In particular Intel style interrupt handling requires a dedicated interrupt handler chip (if you by any means need to know what caused an interrupt), while at least 8-bit Motorola, and 6502, has status registers or other ways to query every interrupt generating chip if that chip was the cause of an interrupt (and what within the chip caused it, for chips that for example combine timers with I/O ports). Not that this difference translates directly to different way of “reply APIs”, but maybe it has some influence in what people at first think of when designing that type of API? Or is this kind of an inheritance from different mainframe/minicomputer operating systems?

  3. Fernando says:

    @MiaM “I wonder what use case they saw in that?”
    In the document “OS/2 Specifics of Kermit 95” says: “NETBIOS is the preferred protcol to use when transfering files with MS-DOS Kermit or Kermit/2 for OS/2 in a peer-to-peer local area network. NETBIOS is supported over most networking protocols including: Netbeui, IPX, IP, and LU6.2. In addition, it has lower overhead than all other OS/2 implemented networking protocols. ”
    Also MiaM wrote “they could perhaps also have a go at the DECnet for DOS / Pathworks for DOS API:s to use Kermit over LAT and/or CTERM” and that page has this section:
    “Using DECnet PATHWORKS
    DECnet LAT (Local Area Transport) support works in conjunction with DEC’s PATHWORKS For OS/2 product version 2.3 or later, which must be installed, and LATCALLS.DLL must be in your LIBPATH. To make LAT connections from Kermit/2: ”
    So some support is already there (not using NETBIOS).

  4. Michal Necasek says:

    OS/2 based Kermit has been around since the late 1980s. Kermit 95 was a 1995 release as the name suggests, but that’s not at all when things started.

    I’m pretty sure the use case was LANs without a file server, or machines without a file server client installed. TCP/IP was not typically used on a LAN, things ran over IPX or NBF. So NetBIOS was a logical option.

  5. David Goodwin says:

    @MiaM: MS-DOS Kermit apparently supports DECnet LAT and Meridian SuperLAT. Details on Kermit 95s support for LAT and CTERM is in the manual: https://kermitproject.org/k95manual/dec.html

    A start was made on NetBIOS support for Windows but it was never finished. I’ve not yet evaluated what’s involved in finishing it off: https://www.columbia.edu/kermit/ftp/k95source/cknnbi.c

  6. Fernando says:

    I don’t have OS/2 running at the moment or a compiler, but would be interesting to check if an application that uses NETAPI.DLL and another application that uses ACSNETB.DLL in the same machine communicate with each other. Or for that matter an OS/2 16-bit application with an OS/2 32-bit application at the same machine using NETBIOS.

  7. Josh Rodd says:

    This is going entirely off of a rather rusty memory, but a while ago I made a client/server application (essentially a forms-based UI to access an application remotely) and initially used NETAPI.DLL. I had a print copy of the IBM Local Area Network Technical Reference (in a nice, big 3-ring binder) and followed the example code there.

    Lo and behold, the program worked properly on OS/2 Warp Connect (3.0) (MPTS), but didn’t function on OS/2 2.1 with IBM Peer (LAPS). I wrote an alternate client that used ACSNETB.DLL and then it “just worked”.

    The DOS client… I can’t remember if the OS/2 LAN toolkits shipped with a shim that basically implemented either the ACSNETB or the NETAPI interface, or if I ended up just using INT 5Ch. As I recall, the INT 5Ch interface was drop-dead simple.

    As far as whether the two interfaces can communicate on the same machine… yes, they can; I did all the development on the same machine and just had the various clients and server talk to each other. It used NetBIOS sessions. I never bothered with datagrams. All of the clients worked fine on OS/2 4.0 with MPTS and NetBIOS over TCP/IP. The DOS client worked fine on contemporary Windows (Windows 95, NT 4.0, etc.).

    Oh… and one more oddity: at least with MPTS on OS/2 4.0, you could also access NetBIOS via the standard OS/2 socket API using NetBIOS protocol and address family.

  8. Michal Necasek says:

    On DOS, INT 5Ch is NetBIOS, there is no other library or anything in between. At least it’s not necessary to use anything else.

    I wonder why your program didn’t work on OS/2 2.1 using NETAPI.DLL. That interface is just as old as ACSNETB.DLL, although the usage is a little different. From what I can tell, ACSNETB.DLL is a more direct interface with no dependency on the LAN Requester.

    And yes, sockets over NetBIOS were supported by IBM. Don’t know if anyone really used it, but it was a possibility.

    Now I’m interested: Where’s the IBM LAN Tech Ref example code? There was supposed to be a floppy with sample code included, but now I can’t find a copy anywhere.

  9. Josh Rodd says:

    Next time I’m at my dad’s place, I’ll check the IBM Local Area Network Technical Reference… I vaguely recall there was a diskette in there. I based my code off the sample code in the manual itself, though.

    The only guess I have for why it didn’t work (and keep in mind I knew next to nothing about the networking stack back then; I literally learned most of what I knew the time from reading the LAN Tech Ref) is that the network was set up with 802.2 encapsulation for some bizarre reason. I think this was the default when you set up IBMPEER. 802.2 encapsulation made all kinds of bizarre things not work.

  10. Michal Necasek says:

    Archiving the LAN Tech Ref sample programs disk would be terrific!

    All I have seen is this 1988 edition which talks about a sample programs diskette but contains no listings. I also have a newer edition in BookManager format but again, it just says there’s a sample programs diskette and there’s nothing in the manual itself.

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.