Logo
blank Skip to main content

NDIS Driver Development: Why You Need NDIS Drivers and When to Use Them

If your software project requires low-level work with networks, your team must know which types of drivers to choose for different purposes and how to develop them.

To successfully deliver software that monitors networks (such as VPN services, firewalls, and virtualization solutions), youโ€™ll need a special type of driver ใƒผ an NDIS driver.

In this article, we reveal what NDIS is, the types of network drivers it supports, and when to choose NDIS drivers. We also briefly explore why filter drivers are especially important and show how to develop them. This article will be helpful for software project leaders who are looking for expertise in and practical tips on NDIS driver development.

What NDIS is and types of NDIS drivers

Imagine that a protocol driver tries to read or write messages to or from a network. To do that, the driver must use a network adapter. However, there are a variety of adapters on the market, each with its own nuances. To enable connections between protocol drivers and various network adapter drivers, Microsoft and 3Com developed the NDIS specification.

What is NDIS?

The Network Driver Interface Specification (NDIS) is a Windows specification for communication between network device drivers and communication protocol programs. As an API, NDIS provides an interface between protocol drivers and network interface controllers (NICs), allowing various network devices to communicate. And as a library, NDIS acts like a wrapper, abstracting network hardware from network drivers.

What is an NDIS driver?

By NDIS drivers, we mean network adapter drivers supported by the NDIS library. The NDIS library specifies how communication protocol programs like TCP/IP and adapter drivers communicate with each other.

According to the Open Systems Interconnection (OSI) model, NDIS drivers work on the data link layer. This is the layer where network data is transferred to network devices with the help of the hardware abstraction layer.

What are NDIS driver types?

Letโ€™s take a closer look at each of the four NDIS driver types:

4 NDIS driver types

1. Miniport drivers are often used by developers to control network maps and connect to high-level drivers. To work with miniport drivers, engineers usually use functions from NDIS libraries that start with NdisM. However, you can still use other common functions of the NDIS library. Miniport drivers can be connectionless (control NICs for connectionless network media like Ethernet) and connection-oriented (control NICs for connection-oriented network media like ISDN).

Just like all NDIS drivers, miniport drivers use callbacks that are recorded to the NDIS_MINIPORT_DRIVER_CHARACTERISTICS structure. To initialize a miniport driver, we pass this structure to the miniport driver registration function:

C
NdisMRegisterMiniportDriver(
                DriverObject,
                RegistryPath,
                &GlobalData,
                &MPChar,
                &NdisDriverHandle);

2. Protocol drivers are considered the highest-level drivers within the NDIS driver hierarchy. They use NDIS functions to send and receive data packets, communicating with underlying NDIS drivers.

You can also set callbacks using protocol drivers. To do that, pass the NDIS_PROTOCOL_DRIVER_CHARACTERISTICS structure to the NdisRegisterProtocolDriver registration function.

3. Intermediate drivers are hybrid drivers, typically layered between miniport drivers and transport protocol drivers. Intermediate drivers can see all network traffic within a system. They can also act as a basis for software that provides fault tolerance and load balancing for network adapters, such as Network Load Balancing Provider by Microsoft.

To register this driver, we use an approach that combines registration workflows for miniport and protocol drivers:

  • Fill out the NDIS_MINIPORT_DRIVER_CHARACTERISTICS structure and pass it to the NdisMRegisterMiniportDriver function.
  • When calling the NdisMRegisterMiniportDriver function, specify the NDIS_INTERMEDIATE_DRIVER flag.
  • Fill out the NDIS_PROTOCOL_DRIVER_CHARACTERISTICS structure and pass it to the NdisRegisterProtocolDriver function.
  • Call the NdisIMAssociateMiniport function, passing miniport and transport driver handles to it.

4. Filter drivers can monitor and modify network interactions between protocol and miniport drivers. Though this may sound similar to the description of an intermediate driver, filter drivers are created to filter network traffic, so they are faster to develop and simpler to use.

These drivers can filter all input and output communications of a miniport adapter, choose certain filtration types (data packets or message managers), and skip certain communications that are not to be filtered.

NDIS filter drivers are great for low-level work with networks, as they offer a convenient API for development and use. These drivers are perfect for creating solutions that analyze, filter, and transfer data packets. Common examples of such solutions are VPN services that provide opportunities to redirect traffic and filter connections yet guarantee that not a single data packet is missed.

Weโ€™ll take a closer look at how to initialize this driver type a little later. But first, letโ€™s discuss in which cases your team should use NDIS drivers.

Need a custom driver?

Ensure efficient network traffic monitoring, filtering, and redirection with professionally developed driver solutions from Aprioritโ€™s top engineers!

When to choose NDIS drivers: Aprioritโ€™s experience

While building software, engineers might include Windows Filtering Platform (WFP) drivers to the development plan, as these drivers:

  • Combine LSP, TDI, and NDIS technologies
  • Allow you to see which process has sent data packets
  • Can be used for developing firewalls, antivirus software, and network analysis solutions

Since WFP drivers serve multiple purposes and are so advanced, why use NDIS drivers?

Letโ€™s explore two major cases when developing NDIS drivers is a better choice than creating WFP drivers:

  1. WFP works on OSIโ€™s higher layers and doesnโ€™t allow for interacting with network adapters. If you need to work on the hardware abstraction level, choose NDIS drivers.
  2. If software transfers traffic to adapters using its own NDIS drivers, you can work with such traffic only by also developing your own NDIS drivers. You canโ€™t use WFP drivers to intercept, analyze, and modify data packets in such a case, as packets would miss the network and transport layers, going straight to the data link layer.
When to choose NDIS drivers over WFP

One of our projects showed us that standard WFP drivers canโ€™t intercept network traffic launched from virtual machines. The reason is the way programs like VirtualBox and VMware Workstation act when we configure the network connection to the Bridged mode. They transfer all traffic from programs running inside a virtual machine using their own NDIS driver protocol. This way, traffic bypasses all WFP drivers running on a host computer, meaning you canโ€™t use WFP drivers to intercept the traffic.

Therefore, we had to develop our own NDIS driver that could work on the OSIโ€™s data link layer, intercept traffic, and work with it. When choosing the NDIS driver type, Apriorit engineers decided to go with a filter driver, as it works on low layers and offers rich functionality for analyzing and modifying network traffic.

By successfully delivering a filter driver, we received access to data packets that have been transferred from virtual machines, bypassing WFP drivers. We also gained the ability to redirect these data packets and significantly improved the VPN service for our clientโ€™s software.

Now, letโ€™s take a closer look at how to create and use an NDIS filter driver.

Related project

Improving a Windows Audio Driver to Obtain a WHQL Release Signature

Find out how we helped a British audio technology company attract more customers across the globe by reworking their Windows driver and delivering a macOS version.

Project details
Improving a Windows Audio Driver to Obtain a WHQL Release Signature

How to develop and initialize an NDIS filter driver

If your development team wants to follow through with our short tutorial, youโ€™ll need Visual Studio, as it already contains a template for the NDIS filter driver project. You can explore a filter driver template on Microsoftโ€™s GitHub page.

Letโ€™s pay attention to the main function ใƒผ DriverEntry. This function is responsible for driver initialization, including setting the callbacks that establish the work logic.

C
#pragma NDIS_INIT_FUNCTION(DriverEntry)
NDIS_HANDLE         FilterDriverHandle;
NDIS_HANDLE         FilterDriverObject;

Now, letโ€™s use the NDIS_FILTER_DRIVER_CHARACTERISTICS structure. We recommend leaving the default settings for some parameters, such as those that point to revision, version, and flags.

C
NTSTATUS
DriverEntry(
    PDRIVER_OBJECT      DriverObject,
    PUNICODE_STRING     RegistryPath
    )
{
    UNREFERENCED_PARAMETER(RegistryPath);
    FilterDriverObject = DriverObject;
    NDIS_FILTER_DRIVER_CHARACTERISTICS FChars;
    NdisZeroMemory(&FChars, sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS));
    FChars.Header.Type = NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;
    FChars.Header.Size = sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS);
    FChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_2;
    FChars.MajorNdisVersion = FILTER_MAJOR_NDIS_VERSION;
    FChars.MinorNdisVersion = FILTER_MINOR_NDIS_VERSION;
    FChars.MajorDriverVersion = 1;
    FChars.MinorDriverVersion = 0;
    FChars.Flags = 0;
    NDIS_STRING ServiceName = RTL_CONSTANT_STRING(FILTER_SERVICE_NAME);
    NDIS_STRING UniqueName = RTL_CONSTANT_STRING(FILTER_UNIQUE_NAME);
    NDIS_STRING FriendlyName = RTL_CONSTANT_STRING(FILTER_FRIENDLY_NAME);
    FChars.FriendlyName = FriendlyName;
    FChars.UniqueName = UniqueName;
    FChars.ServiceName = ServiceName;
    FChars.SetOptionsHandler = FilterRegisterOptions;
    FChars.AttachHandler = FilterAttach;
    FChars.DetachHandler = FilterDetach;
    FChars.RestartHandler = FilterRestart;
    FChars.PauseHandler = FilterPause;
    FChars.SetFilterModuleOptionsHandler = FilterSetModuleOptions;
    FChars.OidRequestHandler = FilterOidRequest;
    FChars.OidRequestCompleteHandler = FilterOidRequestComplete;
    FChars.CancelOidRequestHandler = FilterCancelOidRequest;
    FChars.SendNetBufferListsHandler = FilterSendNetBufferLists;
    FChars.ReturnNetBufferListsHandler = FilterReturnNetBufferLists;
    FChars.SendNetBufferListsCompleteHandler = FilterSendNetBufferListsComplete;
    FChars.ReceiveNetBufferListsHandler = FilterReceiveNetBufferLists;
    FChars.DevicePnPEventNotifyHandler = FilterDevicePnPEventNotify;
    FChars.NetPnPEventHandler = FilterNetPnPEvent;
    FChars.StatusHandler = FilterStatus;
    FChars.CancelSendNetBufferListsHandler = FilterCancelSendNetBufferLists;
// Install the driver unload function
DriverObject->DriverUnload = FilterUnload;
//Register the driver after filling out the characteristics structure
        NDIS_STATUS status = NdisFRegisterFilterDriver(DriverObject, FilterDriverObject, &Fchars, &FilterDriverHandle);
        if (status != NDIS_STATUS_SUCCESS)
        {
		   // If driver registration failed, deregister it
            NdisFDeregisterFilterDriver(FilterDriverHandle);
        }
    return status;
}

Once you have successfully initialized the NDIS filter driver, you can start using it for your solution.

If you need to filter, redirect, or in some other way modify the traffic that goes to an adapter, use the following callback functions when working with packets:

  • FilterSendNetBufferLists ใƒผ Allows a filter driver to filter a linked list of NET_BUFFER_LIST structures that are called NET_BUFFER. The NET_BUFFER structure stores information about data packets, and you can modify that information.
  • FilterReturnNetBufferLists ใƒผ Returns a linked list of NET_BUFFER_LIST structures and associated data to a filter driver.
  • FilterSendNetBufferListsComplete ใƒผ Completes a send request that a filter driver has started by calling the SendNetBufferLists function.
  • FilterReceiveNetBufferLists ใƒผ Requests a filter driver to process a receive indication.
  • FilterCancelSendNetBufferLists ใƒผ Cancels the transmission of all NET_BUFFER_LIST structures that are marked with a specified cancellation identifier.

To explore more examples of Windows drivers, visit Microsoftโ€™s GitHub page.

Read also

Controlling and Monitoring a Network with User Mode and Driver Mode Techniques: Overview, Pros and Cons, WFP Implementation

Whether you want to detect viruses, block undesired traffic, or limit access to network resources, understanding how to control and monitor traffic is essential. Read on to discover proven ways to monitor and modify network traffic on Windows by applying user mode and driver approaches.

Learn more
User Mode and Driver Mode for network monitoring

How Apriorit can help you with driver development

Our driver development teams have rich experience delivering solutions that meet our clientsโ€™ technical requirements and business needs. Apriorit engineers make sure that all solutions we develop not only function as intended but have a high degree of data protection and comply with cybersecurity standards.

We can help you with delivering different types of solutions, including:

Drivers and driver solutions Apriorit can build for you

Apriorit engineers create driver solutions for different industries. A few examples of our work include:

  • Developing drivers for virtual reality headsets. Our client managed to reduce the time to market for their device by developing and testing drivers in parallel with development of the device itself. Thanks to receiving efficient drivers that enable fast data transmission with low latency, they successfully released their product and started receiving positive feedback from their customers.
  • Improving an audio driver to pass a Microsoft certification. IRIS ensured the availability of their AI driver noise canceling app for both macOS and Windows users thanks to thorough driver testing and improvements by Aprioritโ€™s team. As a result of our collaboration, IRIS obtained a WHQL release signature and reached out to even more customers across the globe.
  • Delivering a solution for blocking USB devices. Our client increased the value of their product and their competitive advantage thanks to a professionally developed driver from Apriroit engineers. After our collaboration, the client launched their software for blocking device connections to USB ports and allowing connections with only client-approved devices.
  • Creating custom USB Wi-Fi drivers. Our client received a ready solution in four months instead of the eight months that it usually takes to develop a new Windows driver from scratch. We managed to significantly enhance their solution and provide end users with a user interface and tools for Wi-Fi network analysis by incorporating the developed driver into their product.

We develop custom drivers for Windows, Linux, and macOS and are ready to assist you with projects of any complexity.

Conclusion

Although NDIS technology is not new, itโ€™s still essential for low-level driver work. In some cases, NDIS drivers can accomplish tasks that even WFP drivers canโ€™t. This driver type is especially useful for developing various cybersecurity products and solutions for filtering and redirecting traffic.

Whether you have a new software project in mind or need assistance with enhancing an existing one, Aprioritโ€™s driver development specialists are ready to help. Ensure flawless driver work and robust data protection by entrusting your technical challenges and non-trivial tasks to our experts.

Level up your network game!

Evaluate your driversโ€™ security and efficiency, detect and eliminate vulnerabilities, and receive custom solutions with the help of Aprioritโ€™s professional driver development services.

Have a question?

Ask our expert!

Tell us about
your project

...And our team will:

  • Process your request within 1-2 business days.
  • Get back to you with an offer based on your project's scope and requirements.
  • Set a call to discuss your future project in detail and finalize the offer.
  • Sign a contract with you to start working on your project.

Do not have any specific task for us in mind but our skills seem interesting? Get a quick Apriorit intro to better understand our team capabilities.