The DOS Packet Driver API: One Interrupt Interface for Many Network Cards
How DOS packet drivers expose Ethernet classes, receiver callbacks, send operations, handles, interrupt vectors, and hardware-specific configuration.
DOS has no universal in-kernel TCP/IP stack. Packet drivers solved the hardware portability problem by placing a small NIC-specific resident program below network applications and exposing a common API through a software interrupt. mTCP, WATTCP programs, diagnostics, and other clients can then exchange link-layer frames without knowing every adapter’s register layout.
The driver owns the card; clients own protocols
A packet driver initializes the NIC, handles its hardware interrupt, transfers frames, and implements the packet-driver function interface. It normally does not provide DHCP, ARP, IP, TCP, DNS, or FTP by itself. Those protocols live in the client library or application.
FTP/DHCP/PING application
↓ packet-driver API
resident packet driver
↓ I/O ports, IRQ, DMA/bus operations
network adapter
This separation is why one working driver can support several TCP/IP packages, but only when they cooperate over handles and packet types.
A software interrupt is the rendezvous point
The driver is loaded with a packet interrupt vector, traditionally chosen from a documented range and often written as a hexadecimal value such as 0x60. The exact command line also depends on adapter I/O base, IRQ, connector, and driver model:
LH NICPKT.COM 0x60 5 0x300
That is schematic, not a command for an unknown card. Read the driver’s own documentation. Probing the wrong I/O ports or IRQ on vintage hardware can conflict with a sound card, storage controller, PCMCIA service, or another NIC.
Clients discover the signature and call functions through the vector. If another TSR already owns it, loading the driver can fail or overwrite an unrelated service. Inventory interrupt use before changing the vector and keep a known-good boot menu.
Receiver registration uses handles and callbacks
A client requests access to a class/type and supplies a receiver callback. The driver returns a handle that identifies the registration. Incoming packets matching that request are delivered through a two-stage convention: the driver asks the receiver for a buffer, then calls again after filling it.
The callback executes in an interrupt-sensitive context. It must be fast, preserve required registers, provide stable memory, and defer expensive protocol work. Blocking DOS calls or unsafe reentrancy inside a hardware-delivery path can corrupt state.
Multiple clients and “promiscuous” or multicast modes depend on driver capabilities. Do not assume a packet driver multiplexes every registration perfectly; old drivers vary, and some network stacks expect to be the only client.
Sending is asynchronous at the hardware boundary
The API accepts a complete link-layer frame for transmission. A successful function return can mean the driver accepted or sent the frame according to its implementation; it does not prove the remote host received it. Applications still need ARP resolution, checksums, retry and timeout logic, and protocol acknowledgements.
Ethernet maximum frame size, minimum padding, MAC addressing, and adapter buffers constrain the request. Packet-driver statistics and driver-specific diagnostics help distinguish a local send failure from a cable, duplex, switch, or protocol problem.
Hardware identity remains the difficult part
An NE2000-compatible label is not enough: bus type, I/O address, IRQ, EEPROM configuration, 8/16-bit mode, and clone behavior matter. On PCI, a driver must support the actual chipset and PCI discovery. In a virtual machine, choose a NIC model with a documented DOS packet driver rather than the hypervisor’s newest virtual adapter.
Load Card Services before a PCMCIA packet driver when required. Disable plug-and-play reassignment or reserve resources only through the machine’s supported setup; random IRQ changes can make the card appear dead while breaking another device.
Diagnose one layer at a time
First confirm the driver loads, reports the correct MAC, and keeps a unique interrupt vector. Then run its self-test or packet statistics. Next use a small client to test local packet transmission and ARP, followed by DHCP/static IP, gateway reachability, DNS, and application protocol.
Capture the driver’s version, command line, vector, I/O, IRQ, MAC, link state, mTCP configuration, and packet counts. High-level “timeout” errors are not enough to distinguish missing receive callbacks from wrong DNS.
The packet-driver specification made DOS networking modular. Its boundary is simple, but reliable operation still depends on exact hardware resources, callback discipline, and a protocol stack configured independently above it.
Related:
- FAT32 on FreeDOS: Cluster Addressing, Compatibility, and Practical Limits
- How to Test Windows 3.1 on FreeDOS Without Risking a Working Installation
Sources: