home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 14 Text
/
14-Text.zip
/
ndis2.zip
/
ndis_con.asc
Wrap
Text File
|
1992-06-22
|
58KB
|
1,193 lines
NDIS Concepts
The following article originally appeared in the Winter 1991
Issue of 3TECH, The 3Com Technical Journal.
3TECH is published quarterly by 3Com Corporation, Santa Clara,
CA 95052.
Subscriptions to 3TECH are available at a rate of $35 per
calendar year. To order subscriptions to 3TECH write to 3TECH
Journal, 3Com, P.O. Box 58145, Santa Clara, CA 95052-9953.
All orders must be prepaid and reference 3C2869.
Note: This file has been modified from the original article
to be printable with ascii characters. It uses PC extended
ascii graphics characters to make boxes for figures, so the
printer should support the PC character set to print these
correctly.
NDIS Concepts
The Network Driver Interface Specification (NDIS) is a
standardized interface for OS/2 or DOS network platforms. NDIS
provides access to the network services at the Data Link layer
and is especially useful if the access must be shared. Software
developers who need to employ their own network protocol
implementations can program to the NDIS interface and utilize
NDIS-compliant drivers provided by network hardware vendors.
This frees the protocol developer from programming directly to
various network interface cards and solves compatibility problems
on machines with multiple protocols.
This article explains why the Network Driver Interface
Specification was developed, and describes its organization and
operation. Some of the information is general, and will be of
interest to a broad group of people involved with networks. A
good deal of the information is quite detailed and technical. It
is intended primarily to give network programmers an overview of
NDIS and what is involved in binding a protocol to an vendor-
supplied MAC driver for a network adapter board.
The Old Way
Traditionally, network software vendors for the MS-DOS
environment have used ad hoc methods to implement the protocols
and drivers that link applications to their resident network
hardware. The entity that performs these network functions and
provides communication between applications is usually referred
to as a protocol stack. In the OSI Reference Model, the stack
would correspond to the Data Link, Network, Transport, and
Session layers, with some stacks possibly including higher
layers. At the stack's top end is a user interface or some type
of applications programming interface (API) and, at the bottom
end, are the interfacing routines that control the network
adapter hardware. In implementation, a stack might consist of
one system driver, multiple drivers, a program, or a combination
of drivers and programs.
Figure 1 shows three alternative stacks that could be used to
perform equivalent network functions. In a typical
implementation (for example, NetBIOS over XNS, in figure 1) the
Data Link, Network, and Transport layers might be implemented as
three separate system drivers, and the Session layer as a TSR
program. Usually, the interfacing between the layers would be
accomplished through a proprietary interface developed by the
vendor and the application would communicate to NetBIOS via
software interrupts. This works fine in a homogeneous network
environment, but as networks grow more complex, it is becoming
1
desirable to have the flexibility to utilize mixtures of
different protocols, application interfaces, and network media.
Figure 1. Typical Protocol Implementations Without NDIS
OSI NetBios Sockets
Model over over
XNS TCP/IP
┌──────────────┐ ┌─────────────┐ ┌─────────────┐
│ Application │ │ │ │ │
├──────────────┤ │ Application │ │ Application │ -─ Application
│ Presentation │ │ │ │ │ Software
├──────────────┤ ├─────────────┤ ├─────────────┤
│ Session │ │ NetBIOS │ │ BSD │ -- API
│ │ │ │ │ Socket │
├──────────────┤ ├─────────────┤ ├─────────────┤
│ Transport │ │ SPP │ │ TCP │ \
├──────────────┤ ├─────────────┤ ├─────────────┤ ├ Protocol
│ Network │ │ IDP │ │ IP │ /
├──────────────┤ ├─────────────┤ ├─────────────┤
│ Data Link │ │ Driver │ │ Driver │ -- Adapter
│ │ ├─────────────┤ ├─────────────┤ Driver
├──────────────┤ ├─── H/W ───┤ ├─── H/W ───┤
│ Physical │ │ Media │ │ Media │
└──────────────┘ └─────────────┘ └─────────────┘
The Problem to be Solved
Compatibility issues between various networking implementations
can make it difficult or impossible to accomplish some seemingly
simple tasks. For example, assume that we have an Ethernet
network that has two types of file servers attached. One server
runs an XNS protocol with NetBIOS at the Session layer. The
other server runs a TCP/IP protocol with a Berkeley Socket
Session interface.
We would like to write a program to run on a workstation that can
copy a file from the first server to the second. In this
example, let's say we have two sets of software from two vendors
that are designed to communicate with each of the servers, and
that the vendors have defined a programmer's interface that
should allow us to write a program which talks to the two stacks.
Assuming that we have enough memory to load both stacks at one
time, we will probably find that our biggest configuration
problem occurs at the bottom of the stacks.
At the Data Link layer, each of the vendors has supplied us with
a driver for use with their protocol stack that can control the
EtherLink II adapter board that we have in our station. Most
2
likely, we will find that each of these drivers expects to have
exclusive ownership and control of the EtherLink II. As one of
the drivers tries to control the board, it interrupts or corrupts
the functions being attempted by the other driver. What is
needed is one driver that can control the adapter and be shared
by the two protocols.
In May of 1988, 3Com and Microsoft released NDIS, which was
jointly developed in conjunction with LAN Manager. The NDIS
specification is a standard designed to alleviate compatibility
issues for both OS/2 and DOS network platforms. The NDIS
specification should be beneficial to both the protocol-level
network software developer, who now has a standard interface
available, and the user, who gains from the flexibility and
interoperability advantages of protocols using NDIS.
NDIS Organization
All network software components compliant with NDIS definitions
are drivers. These drivers can be classified into two types:
protocol drivers, and Media Access Control (MAC) drivers. NDIS
allows protocol drivers to be device drivers, TSR's, or DOS
applications, however, for this discussion, we are going to
assume that all NDIS drivers are device drivers--the simplest and
most common implementation.
The MAC driver forms the bottom layer of the stack and is the
driver that directly controls the network hardware. The
remaining higher layers of the protocol stack are implemented in
one or more protocol drivers.
The MAC layer is a sublayer within the OSI Data Link layer that
is defined by IEEE 802 specifications. This layer is the
appropriate point for a driver that manages the network hardware
and implements the transmission and reception of network data
packets. NDIS MAC drivers are provided by 3Com and many other
network hardware vendors (see Table 1 for a partial list) and can
be used with any vendor's NDIS compliant protocol drivers.
3
Table 1. Companies Supporting NDIS
┌───────────────────────────────────────────────────────────────┐
│ Companies with NDIS MAC Drivers │
│ │
│ Note: The entire list of companies shipping NDIS MAC drivers │
│ is too long for this article, but includes: │
│ │
│ 3Com Interlan │
│ AST Research Proteon │
│ AT&T Tiara │
│ Compaq Ungermann-Bass │
│ Exelan Western Digital │
│ IBM │
│ │
│ Companies with OS or Application Supporting NDIS │
│ │
│ 3Com - LAN Manager │
│ AT&T - LAN Manager │
│ Banyan - Vines (workstation) │
│ DEC - LAN Works │
│ FTP - PC/TCP │
│ IBM - LanServer, OS/2 Extended │
│ Microsoft - LAN Manager │
│ Pacer - Pacerlink │
│ Sun - PC-NFS │
└───────────────────────────────────────────────────────────────┘
NDIS Stacks
All NDIS drivers, both MAC and protocol, share a basic common
modular structure. Each driver has an upper and lower boundary.
The drivers are linked to form a stack by connecting, or binding,
the upper boundary of one driver to the lower boundary of another
driver during the binding portion of driver initialization. This
binding process can be repeated multiple times, linking several
drivers, daisychain fashion, to form the stack. The MAC driver,
at the bottom of the stack, always has its lower boundary
connected to the physical layer--the network hardware.
The simplest configuration of drivers is one MAC driver
supporting one network adapter card, bound to a single protocol
driver that spans from the MAC layer to the Session layer (see
Figure 2). This forms a single protocol stack of two drivers.
Optionally, the protocol part of this stack might be made using
two or more protocol drivers to form a single stack of three or
more drivers. NDIS also allows us to have two completely
parallel stacks in one machine, each with its own adapter card
and MAC driver, to implement two different protocols.
4
Figure 2. NDIS - Single Protocol, Single MAC
OSI IEEE Using
Reference Model NDIS
Model ┌─────────────┐
│ ABC Protocol│
■ ■ ■ LLC ■ │ Driver │
│ │ ├─────────────┤ NDIS -╞═════════════╡
│ │ │ │ Intfc │ NDIS │
│ Data Link │ │ MAC │ │ MAC Driver │
│ │ │ 802.3/802.5 │ ├─────────────│
│ │ │ │ │ 3Com LAN │
│ │ │ │ │ Adapter │
├──────────────┤ ├─────────────┤ ├─────────────│
│ Physical │ │ Network │ │ Network │
│ │ │ Cabling │ │ Cabling │
└──────────────┘ └─────────────┘ └─────────────┘
Figure 3. NDIS - Multiple Protocols, Single MAC
OSI IEEE Using
Reference Model NDIS
Model ┌──────────┬──────────┐
│ABC Protoc│XYZ Protoc│
│ Drvr ┌───┴───┐ Drvr │
■ ■ ■ LLC ■ │ │ Vector│ │
│ │ ├─────────────┤ ╘═══╤══╧═══════╧══╤═══╛
│ │ │ │ / │ NDIS │
│ Data Link │ │ MAC │ NDIS │ MAC Driver │
│ │ │ 802.3/802.5 │ Intfc ├─────────────│
│ │ │ │ │ 3Com LAN │
│ │ │ │ │ Adapter │
├──────────────┤ ├─────────────┤ ├─────────────│
│ Physical │ │ Network │ │ Network │
│ │ │ Cabling │ │ Cabling │
└──────────────┘ └─────────────┘ └─────────────┘
More importantly, NDIS lets us have just one adapter card and a
single MAC driver with the MAC driver bound to two separate
protocol drivers (see Figure 3). Therefore, two protocols (XNS
and TCP/IP, for instance) can share the same MAC driver and
adapter card. This configuration solves the problem discussed
earlier in which files needed to be copied from two servers
running different protocols.
To complete the picture, we can also have two adapter cards and
MAC drivers, with both the MAC drivers bound to one protocol
5
driver (Figure 4). This configuration could be used to create a
network bridge with one protocol connected to two networks.
Figure 4. NDIS - Single Protocol, Multiple MACs
OSI IEEE Using
Reference Model NDIS
Model NDIS ┌─────────────┐
Intfc │ JKL Protocol│
■ ■ ■ LLC ■ \ │ Driver │
│ │ ├─────────────┤ ╒══════╧══════╤══════╧══════╕
│ │ │ │ │ NDIS │ NDIS │
│ Data Link │ │ MAC │ │ MAC Driver │ MAC Driver │
│ │ │ 802.3/802.5 │ ├─────────────┼─────────────┤
│ │ │ │ │ 3Com LAN │ 3Com LAN │
│ │ │ │ │ Adapter │ Adapter │
├──────────────┤ ├─────────────┤ ├─────────────┼─────────────┤
│ Physical │ │ Network │ │ Network │ Network │
│ │ │ Cabling │ │ Cabling │ Cabling │
└──────────────┘ └─────────────┘ └─────────────┴─────────────┘
Driver Structures
The drivers communicate with each other by a defined set of
primitives. The NDIS document has clearly specified a set of
primitives for the interface between the MAC driver and protocol
driver and for managing the NDIS driver binding process.
Although it is possible to implement a protocol stack with
multiple protocol drivers, currently no primitives are defined by
NDIS for these upper layers. This is not a serious limitation,
since a stack with multiple protocol drivers would generally have
all of the protocol drivers common to one vendor. There is less
need for a standardized interface between protocol drivers than
at the MAC layer where sharing resources, and multiple vendors,
is more likely.
Each driver contains a series of module characteristic data
structures that provide information describing the purpose and
capabilities of the driver, and that manage the linkage and
operation of the driver during and after initialization.
The main structure is called the Common Characteristics Table and
contains the name of the driver and version information. This is
the highest level table for a driver; other types of
characteristics tables are located from pointers in this table.
The Common Characteristics table also contains basic information
about what type of binding is supported at the upper and lower
boundaries of the driver. The binding information is in the form
of a byte identifying the OSI layer that is supported for the
6
boundary. This byte can be examined by other drivers to
determine if it is appropriate to bind to the driver.
The common characteristics table contains pointers to the other
module characteristics tables -- the service specific
characteristics table, service specific status table, and upper
and lower dispatch tables. These tables give specific
information related to the service that the driver performs,
manage its operation, and record linkage points to other drivers
after the driver is bound.
Managing Binding and Initialization
To form the protocol stacks from the individual drivers we need
to get the right drivers hooked together in the desired
sequence. This is accomplished in the initialization and binding
process. Three components are used to manage and control the
process -- PROTOCOL.INI (an ASCII configuration parameter file),
PROTMAN.DOS or PROTMAN.OS2 (the protocol manager -- a special
driver), and NETBIND.EXE (a program that initiates the final
driver binding process).
The initialization and binding process is essentially the same
whether the operating system is DOS or OS/2. Some minor
adjustments need to be made (for instance, selecting either
PROTMAN.DOS or PROTMAN.OS2) and some different parameters may be
required, but the discussion that follows applies to either
environment.
The ASCII file PROTOCOL.INI contains the instructions for
assembling the protocol stack or stacks from the NDIS network
drivers. It also contains parameters that are needed to
configure the individual drivers. At CONFIG.SYS initialization
time, the Protocol Manager Driver reads this file. The file is
created -- much as CONFIG.SYS is created -- either directly, by
the administrator typing the information with an editor, or by
some type of installation program.
The PROTOCOL.INI information is grouped into a number of logical
sections of the form:
[module name]
parameter=value
The module name is the name of the NDIS driver, as contained in
the common characteristics table for the driver. There will be
one module section for each of the NDIS drivers that describes
the driver's configuration. Each section can have multiple
parameters, but must have at least one, the DRIVERNAME.
Figure 5 shows the contents of a simple PROTOCOL.INI file that
has entries for three drivers. The first is Protocol Manager,
7
the special driver that controls the binding process -- more
about its purpose later. In PROTOCOL.INI the Protocol Manager
entry is currently optional, but it may be required in the
future, so it's a good idea to include it. The second module
section is for the EtherLink II adapter's MAC driver, and the
last section is for an arbitrary protocol driver.
Figure 5. PROTOCOL.INI File Contents
;***************************
; Example PROTOCOL.INI file
;***************************
[PROTMGR]
DRIVERNAME=PROTMAN$
[ETHERLINKII]
DRIVERNAME=ELNKII$
INTERRUPT=3
TRANSCEIVER=EXTERNAL
[PROTOTST]
DRIVERNAME=PROTO$
BUFFSIZE=2048
BINDINGS=ETHERLINKII
Notice that, in each section, the first parameter is DRIVERNAME=.
This parameter must be included and must specify a name that
uniquely defines the NDIS module. In most cases it will be the
driver name that the driver registers to the operating system
during initialization. The driver determines the name that must
be used, because the driver uses the DRIVERNAME entries as a key
when searching PROTOCOL.INI data for its relevant module section.
Any number of additional, optional parameter entries can be
included in a module section. One purpose of these parameters is
to allow control of the driver configuration. A set of valid
configuration options will be defined for any particular driver.
In the case of the ETHERLINKII section in Figure 5, we have
selected two of the possible options for this driver.
INTERRUPT=3 tells the driver to use hardware interrupt channel 3
and TRANSCEIVER=EXTERNAL tells the driver to configure the
adapter for its external transceiver. In the PROTOTST protocol
driver, the BUFFSIZE parameter might direct a protocol to use a
particular size for its internal buffers.
The BINDINGS= parameter is a special parameter that is valid only
for protocol drivers and specifies the module name of the driver
with which the protocol should attempt to bind on its lower
8
boundary. This parameter determines which drivers will be bound
together to form the stack or stacks. In the PROTOCOL.INI of
Figure 5, PROTOTST is bound to the ETHERLINKII driver.
As mentioned earlier, the component of the NDIS environment that
manages the binding process is the Protocol Manager, which has
the file name PROTMAN.DOS for DOS or PROTMAN.OS2 for OS/2.
Protocol Manager has two main functions: it keeps and manages
common data for the NDIS drivers, and it controls the binding
sequence. Functions of the Protocol Manager are needed by the
NDIS drivers during their system level initialization, so the
Protocol Manager driver must be loaded in CONFIG.SYS before any
of the other NDIS drivers.
The Protocol Manager driver was written by 3Com and is available
from both 3Com and Microsoft. Any vendor needing Protocol
Manager or NETBIND.EXE for use in the initialization of their
network software products can obtain them and include them with
their products. Protocol Manager and NETBIND.EXE are also a
standard part of LAN Manager as shipped by 3Com and Microsoft.
Driver Initialization
The Protocol Manager gathers NDIS related information during the
system CONFIG.SYS initialization of the drivers. During its
initialization, the Protocol Manager driver reads the
PROTOCOL.INI file and parses the information into a set of
structures, called the Configuration Memory Image, that are
accessible by the other NDIS drivers. Because the other NDIS
drivers use this information, the Protocol Manager must be the
first NDIS driver to initialize.
As CONFIG.SYS processing continues, the other drivers are
directed to initialize by the operating system. During
initialization they must open the Protocol Manager device
(PROTMAN$) and then issue a GetProtocolManagerInfo primitive to
obtain, from the Protocol Manager, a pointer to the Configuration
Memory Image (the PROTOCOL.INI data). The drivers find the
section of this data that pertains to them and use any parameters
found there to adjust their initialization process. One result
of this is that drivers may modify their loaded size, based on
parameter requirements, to optimize host memory consumption. If
the driver is a protocol and it finds a BINDINGS= parameter, it
will assess whether or not this binding is valid. Finally, the
driver must issue a RegisterModule primitive to the protocol
manager to register itself. During this register, the driver
passes a pointer to its common characteristics table, and for a
protocol driver, a list of modules to which it wants to bind,
based on the BINDINGS= parameter.
9
After CONFIG.SYS processing completes, the Protocol Manager has a
list of the active NDIS drivers, their characteristics, including
entry points, and the desired bindings.
Driver Binding
The actual binding of NDIS drivers starts when some program
issues the BindAndStart primitive call to the PROTMAN$ device.
For all current Microsoft OS implementations this call will come
from the execution of NETBIND.EXE within a BAT or CMD file.
After receiving the BindAndStart directive, Protocol Manager will
take the binding information from the module registrations and
build a binding hierarchy tree. Starting at the bottom of this
tree (the MAC end) the Protocol Manager works up the tree and
issues an InitiateBind primitive to each protocol module that
needs a driver bound on its lower boundary. As part of the
InitiateBind call, the driver is passed a pointer to the common
characteristics table of the module to be bound. The protocol
driver that was instructed to initiate the bind will then issue a
Bind primitive directly to the driver that it wishes to bind.
When the bind completes, each driver will have a pointer to the
common characteristics of the other, and therefore its entry
points.
After the Protocol Manager has processed all of the binding tree,
all the appropriate network drivers will be bound to each other.
The protocol stack is then fully operational and the drivers can
access each other by calling the dispatch entry points for
communication. Figure 6, Driver Initialization and Binding,
summarizes the binding process.
10
Figure 6. Initialization and Binding Process
A. CONFIG.SYS initialization begins.
1. Protocol Manager driver does its initialization.
a. Protocol Manager reads the PROTOCOL.INI file and
builds the Configuration Memory Image.
2. Other NDIS drivers do their initialization.
a. Open the PROTMAN$ device.
b. Issue GetProtocolManagerInfo to gain access to
ProtMan configuration image.
c. Read config parameters from the image and use them
to complete initialization.
d. Issue RegisterModule to register Characteristics
info with Protocol Manager.
B. CONFIG.SYS processing ends.
C. Binding process starts when the NETBIND.EXE program opens
the PROTMAN$ device and issues a BindAndStart to Protocol
Manager.
1. Protocol Manager builds a binding tree from
RegisterModule info.
2. Protocol Manager starts at the bottom and calls
drivers with InitiateBind.
a. Each called driver issues Bind to the specified
module to complete binding.
D. When all modules are bound, Protocol Manager returns from
BindAndStart.
One more factor is involved in the binding process if more than
one protocol is to be bound to a MAC driver. MAC drivers can
only have one binding at their upper boundary. To link one MAC
to multiple protocols, the Protocol Manager inserts a component,
called Vector, between the MAC and the protocols (see Figure 3).
Vector is part of the Protocol Manager and will be bound between
the MAC and each of the protocols. To do this, the Protocol
Manager first binds the MAC driver to Vector by issuing a Bind
11
call to the MAC driver, then it issues an InitiateBind call to
each of the protocols directing them to bind to a Vector entry
rather than the MAC entry.
The basic function of Vector is to route incoming packets between
the protocols. When a packet is received by a MAC driver, it
will issue a notification of the event to its upper boundary.
When vector is involved, it will pass this notification, first to
one, then to the other protocol, until one protocol accepts the
packet or all have rejected it. Other functions can be passed,
essentially directly, between protocols and the MAC, but this
vectoring of incoming packets is key to implementing multiple
protocols on one MAC.
MAC to Protocol Interface and Operation
The main purpose of the NDIS interface is to let the bound
drivers communicate with each other. To that end, the NDIS is
largely concerned with defining a set of functions that dictate
how the MAC driver will communicate with the protocol bound on
its upper layer. Table 2, NDIS Primitives, lists the primitives
that are defined for this MAC-to-Protocol communication. All
communication between the MAC and its bound protocol will be
accomplished using these primitives.
In Table 2, the individual primitives are grouped into the main
functional categories that they perform. In the first group
there are functions for the transmission of network packets from
the protocol through the MAC and onto the network, and for the
reception of packets in the reverse direction. In the control
group are all the functions that the protocol uses to control or
modify the operation of the adapter and MAC driver. The
asynchronous status group contains functions that the MAC uses to
report events to the protocol. Finally, the Binding group has
the functions used to accomplish the driver binding process. The
most important of these have already been described. The
remainder are extensions to allow binding and unbinding of
dynamically loadable protocols. More on this subject later.
12
Table 2. NDIS PRIMITIVES
┌───────────────────────────────────────────────────────────────┐
│ TRANSMIT AND RECEIVE │
│ │
│TransmitChain v Initiate transmission of a frame│
│TransmitConfirm ^ Imply completion of frame │
│ transmit │
│ReceiveLookahead ^ Indicate arrival of received │
│ frame and offer lookahead data │
│TransferData v Request transfer of received │
│ frame from MAC to protocol │
│IndicationComplete ^ Allow protocol to do post- │
│ processing on indication │
│ReceiveChain ^ Indicate reception of a frame in│
│ MAC managed buffers │
│ReceiveRelease v Return frame buffer to the MAC │
│ that owns it │
│ │
│ CONTROL │
│ │
│IndicationOff v Disable indications from the MAC│
│IndicationOn v Enable indications from the MAC │
│InitiateDiagnostics v Start MAC runtime diagnostics │
│ReadErrorLog v Get error log info from MAC │
│SetStationAddress v Set network address of the │
│ station │
│OpenAdapter v Issue open request to network │
│ adapter │
│CloseAdapter v Issue close request to network │
│ adapter │
│ResetMAC v Reset MAC software and adapter │
│ hardware │
│SetPacketFilter v Specify filtering params for │
│ received packets │
│AddMulticastAddress v Specify multicast address for │
│ adapter │
│DeleteMulticastAddress v Remove previously added │
│ multicast address │
│UpdateStatistics v Cause MAC to update statistics │
│ counters │
│ClearStatistics v Cause MAC to clear statistics │
│ counters │
│InterruptRequest v Protocol requests later async │
│ indication from MAC │
│SetFunctionalAddress v Cause adapter to change its │
│ functional address │
│SetLookahead v Set length of visible data for │
│ ReceiveLookahead │
│GeneralRequestConfirmation ^ Confirm completion of previous │
│ General Request (see text for │
│ more explanation) │
│ │
│ ASYNCHRONOUS STATUS │
│ │
│RingStatus ^ Indicate a change in ring status│
│AdapterCheck ^ Indicate error from adapter │
│StartReset ^ Indicate adapter has started a │
│ reset │
│EndReset ^ Indicate adapter has completed │
│ reset │
│InterruptIndication ^ MAC response due to │
│ InterruptRequest │
■ ■■ ■
│ BINDING │
│ │
│InitiateBind p>m Instruct a module to bind to │
│ another module │
│Bind m>m Exchange Characteristic Table │
│ info with another module │
│InitiatePrebind p>m In OS/2 dynamic bind mode, │
│ instruct a module to restart │
│ its prebind initialization │
│InitiateUnbind p>m Instruct a module to unbind │
│ from another module │
│Unbind m>m Delete linkage info with │
│ another module │
│GetProtocolManagerInfo m>p Retrieve pointer to │
│ Configuration Image │
│RegisterModule m>p Register Characteristics and │
│ Bindlist with Protocol Manager │
│BindAndStart e>p Initiate the binding process │
│GetProtocolManagerLinkage m>p Get entry point for Protocol │
│ Manager │
│GetProtocolIniPath d>p Get file path for the │
│ PROTOCOL.INI file │
│RegisterProtocolManagerInfo d>p Dynamic mode, register new │
│ Configuration Image │
│InitAndRegister d>p Dynamic mode OS/2, restart │
│ prebind initialization │
│UnbindAndStop d>p Dynamic mode, Unbind and │
│ terminate a module │
│BindStatus e>p Retrieve info on current │
│ bindings │
│RegisterStatus e>p Query if a specific module is │
│ registered │
│ │
│ KEY: │
│ ^ - MAC to protocol │
│ v - protocol to MAC │
│ p>m - Protocol Manager to driver module │
│ m>p - driver module to Protocol Manager │
│ e>p - ? to Protocol Manager; ? is normally an │
│ executable program │
│ d>p - dynamic protocol or control program to │
│ Protocol Manager │
└───────────────────────────────────────────────────────────────┘
The center column of the primitive table has a symbol that
indicates the direction in which the primitive calls are passed.
To submit a primitive, the caller driver pushes a series of
parameters on the system stack and calls an entry point in the
called driver. The entry points are known to the calling driver
as a result of the binding process. The common characteristics
table, whose address was passed during binding, has dispatch
tables chained off of it. The defined entry points for the
driver are in a dispatch table.
14
The MAC driver's upper dispatch table and the addresses it
contains are shown below:
MAC Upper Dispatch Table
GeneralRequest
TransmitChain
TransferData
ReceiveRelease
IndicationOn
IndicationOff
These are the entry points that the protocol driver will call to
request primitive execution by the MAC. All of these, except
GeneralRequest, are called direct primitives because they serve
just the one primitive function implied by the entry name. The
GeneralRequest entry serves the remainder of the primitive calls,
other than binding, that are passed to the MAC. In Table 2, the
GeneralRequest primitives are all the primitives in the group
labeled CONTROL, except IndicationOn and IndicationOff, which
have their own direct entries.
The Direct Primitives have their own entry points because these
are performance-critical functions. The primitives employing the
GeneralRequest entry, being less critical, can share a common
entry. The GeneralRequests identify themselves by passing an
opcode as one of their parameters.
On the protocol driver side, the protocol lower dispatch table
defines the entry points from the MAC to the protocol. The table
and its contents are as follows:
Protocol Lower Dispatch Table
GeneralRequestConfirm
TransmitConfirm
ReceiveLookahead*
IndicationComplete
ReceiveChain*
Status*
* denotes Indications
All of these entries except Status are direct. Status is the
entry for the asynchronous status group in the primitive table,
and these primitive calls also have an opcode that identifies the
type so they can share one entry. In a sense,
GeneralRequestConfirm can also be viewed as a shared entry.
15
There is only one primitive for this entry, but it is generated
by the MAC at the end of any of the GeneralRequests to the MAC
and contains the request handle of the original primitive request
to the MAC. Therefore, it is shared functionally in response to
all of the GeneralRequest primitives.
Some of the entries in this list are marked with an asterisk to
show that they are Indications. Indications are a special class
of requests that imply some special handling. In implementation,
they are usually associated with notifications to the protocol
that are made from the MAC while it is in interrupt context.
Because of this, the protocol is required to handle Indications
as efficiently as possible. (For example, it might put the
received frame on a queue.) After the protocol processes the
indication, it returns control to the caller, the MAC. The MAC
will enable as much interrupt processing as possible and then
call IndicationComplete to give the protocol an opportunity to
perform more processing on the Indication in a less critical mode
(e.g., to decode the previously queued receive frame).
Transmit and Receive
Information in Table 2 identifies the basic purpose of each NDIS
Primitive. Of these, transmit and receive are the key functions
at the MAC-protocol interface level, so let's examine the
primitives serving these functions in a little more detail.
Network packets, or frames, are the data units that are
transferred between the MAC and the protocol by the transmit and
receive primitives. These packets include all the information,
other than hardware related functions such as preamble and
checksum, that will be sent out on the network medium. As a
result, the protocol, on transmit, must build the entire packet,
including data link fields such as source and destination
addresses. Likewise, on receive, the protocol must process the
packet down to these levels.
The passing of packet data across the interface between the
protocol and MAC is accomplished, whenever possible, by
exchanging pointers to buffers or to a descriptor that, in turn,
points to several data buffers. The objective is to avoid
unnecessary, time-consuming copying of data between buffers.
In transmit, the packet data buffers are owned by the host system
and managed by the protocol driver. NDIS defines a structure,
the transmit data buffer descriptor, that allows the packet data
to be contained either in one buffer, or in a series of chained
buffers. To initiate a transmit, the protocol assembles the
packet data into buffers, puts the buffer addresses in the buffer
descriptor structure, and calls the MAC with the TransmitChain
primitive. The primitive contains a pointer to the buffer
descriptor.
16
The MAC has two options for processing the transmit. The MAC
will choose one or the other at its own discretion; the protocol
must be capable of handling either. In the first, called
synchronous transmission, the MAC copies all the packet data and
returns to the protocol with a code signifying that the data
buffers are free and the transmit is complete. Optionally, the
MAC can return with a code signifying that the transmit is queued
(this is called asynchronous transmission). It implies that the
buffers are not free and the transmit has not yet completed.
Later, after the MAC has copied all the transmit data, it will
call the protocol with a TransmitConfirm primitive (the
asynchronous response) to inform the protocol that the buffers
are now free and the transmit is complete.
An additional feature available in transmit is immediate data.
The protocol has the option of beginning the transmit buffers
with up to 64 bytes of immediate data. This immediate data, if
present, is always the first data to be transmitted. The MAC
must fully process or copy this data before returning from the
TransmitChain call, even if it will asynchronously process any
remaining data buffers for the call. This feature allows the
protocol to have a small locally managed buffer that only needs
to be valid during the TransmitChain primitive call. A protocol
might use this for building packet header information, or for
entire small protocol-generated packets, such as
acknowledgements.
For receiving packets, the process can work in one of two ways:
using ReceiveLookahead and TransferData primitives, or using the
ReceiveChain primitive. The method that is used is determined by
the MAC, depending on how the MAC and adapter can handle data
buffering. It is generally a function of whether the adapter has
on-board receive buffers that use I/O or DMA to transfer the
data, or whether the adapter buffers are memory-mapped and
accessible directly by the host.
For buffers on the adapter that use programmed I/O or DMA to
transfer the data, the reception process will use a
ReceiveLookahead and TransferData pair of primitives. When the
MAC has received a packet that it wants to present to the
protocol, it indicates this by calling the ReceiveLookahead
primitive of the protocol.
The ReceiveLookahead call contains a pointer to a short portion
of the data at the beginning of the packet. This usually means
that the MAC must have first DMA'ed this lookahead data to a
buffer in the host.
At this point, the protocol driver can examine the lookahead data
to determine if it wants the packet. In some cases, the packet
may not be of interest to the protocol. If the packet is not
needed, the protocol can return to the MAC indicating a reject
and that the receive is complete. If the packet is needed, the
17
protocol calls the TransferData primitive of the MAC which
results in the MAC transferring the remainder of the data to a
protocol buffer.
The purpose of the ReceiveLookahead implementation is to avoid
unnecessary data transfers between the MAC and the protocol.
This technique improves the efficiency of the network stack.
If the adapter has receive buffers that are accessible as host
memory, receive will be implemented with the ReceiveChain
primitive. For this type of buffering, the MAC will own and
manage the receive buffers. For flexibility, this mode has a
ReceiveChain buffer descriptor structure, similar to the transmit
structure, that lets multiple separate buffers be joined for one
packet transfer. When the MAC has a received packet to present
to the protocol, it builds a buffer descriptor for the packet and
calls the protocol with ReceiveChain.
When the protocol gets the ReceiveChain Indication, it has two
options. In the simplest case, the protocol can copy all of the
packet data and return to the MAC specifying that the receive is
complete and the buffers are free. In the other case, the
protocol can defer copying the buffers and return to the MAC
specifying that the buffers are still in use. The protocol will
later complete the copying of the buffers and then call the MAC
with a ReceiveRelease primitive to indicate that the buffers are
now free and the receive is done.
In all of these receive scenarios, the primitive calls issued to
the protocol are indications. This means that the protocol
drivers need to observe certain rules and that the MAC must issue
an IndicationComplete call to the protocol as part of the
process. See the NDIS document for more information about these
indication issues.
Dynamic Binding
As mentioned earlier, some primitives for binding which haven't
been discussed are provided to support dynamic binding. Dynamic
binding is a new concept that has been added in Version 2.0.1 of
the NDIS document. Dynamic binding allows a protocol to be added
to, or removed from an existing network configuration after the
initialization process has completed. The dynamic protocol
driver must be written for this purpose and will normally be
implemented as a TSR or transient program module. See the NDIS
document for a full explanation of dynamic binding and unbinding.
The main advantage of dynamic binding is freeing system memory
until it is actually needed for a particular protocol. This is
most useful in the DOS environment where there is a 640K memory
limit and it is difficult to have multiple protocol stacks loaded
simultaneously.
18
DOS Versus OS/2
NDIS has all the features needed to allow writing network drivers
that will run in either the DOS or the OS/2 environment. A
driver can only be used with one of these operating systems (the
very same driver can't be used for both), but the structure of
the driver can be identical for both environments. We have found
that one set of source code can be used to make versions for both
DOS and OS/2. Where different techniques are required, a small
piece of code can be selected via conditional compile or assembly
statements for the two versions. An example of such a
difference, is that a certain call might need to use Interrupt
21h in a DOS-based driver, versus an IOCTL call for OS/2. A
conditional selection of a few lines of code can implement one or
the other. The make process for the driver will select the
correct environment.
Network device drivers are not very different in structure from
other types of device drivers. The device driver must be written
to conform to the architecture in which it will run - DOS or
OS/2. All of the normal issues apply in writing NDIS drivers for
both of these environments. Several books and articles are
available that explain general driver development issues. See
the list of references at the end of this article for some
titles.
Summary
One of the main goals of the Network Driver Interface
Specification is to save network software developers from
reinventing the wheel for each new version of network adapter
hardware. A protocol that is written with an NDIS interface at
its base should be able to function, unchanged, with many
different types of adapter hardware. In addition, the
manufacturers of the network hardware should be in the best
position to write efficient and bug-free MAC drivers for their
own boards. 3Com and many other vendors (see Table 1) have NDIS
MAC drivers available to support their network hardware.
Using the standardized NDIS interface also allows a new level of
sharing of network resources in a machine. Multiple protocols
and multiple hardware adapters can coexist -- even those from
different vendors. Input was sought from many leaders in the
network industry to guarantee that the specification is flexible
enough to meet most networking needs, however, 3Com carefully
defined the functions so that performance would not be sacrificed
for this flexibility.
19
If you are a network software developer, I hope this article has
provided enough information for you to evaluate whether NDIS can
help in your situation. For the complete description, the NDIS
document can be obtained from 3Com at the following address:
3Com - Network Adapter Division
Software Product Marketing
5400 Bayfront Plaza
P.O. Box 58145
Santa Clara, Ca. 95052-8145
-- Author Bio:
Rex Allers is a Systems Engineer in the Technical Services
Operation at 3Com, specializing in support for developers. Rex
has worked in engineering and support in the computer industry
for longer than he cares to admit, and has been at 3Com since
1986.
References:
1. "Microsoft/3Com LAN Manager Network Driver Interface
Specification"
2. "The Open Book", Marshall Rose, Prentice Hall, 1990
3. "Advanced MS-DOS", Ray Duncan, Microsoft Press, 1986
4. "Writing MS-DOS Device Drivers", Robert S. Lai, Addison
Wesley, 1987
5. "OS/2 Programmer's Guide", Ed Iacobucci, McGraw-Hill, 1988
6. "Writing OS/2 Device Drivers", Raymond Westwater, Addison
Wesley, 1989
20