In the first option, the programmer may work directly with the network interface's device driver. The small overhead required to send and receive a message is of great benefit. Usually this consists of a system call and the time to copy the data from user space into kernel mbufs. However, a device driver's ioctl()s can present quite a challenge to the developer. These calls are often not portable and poorly documented. The network interface would be have to be polled for data because most operating systems will not dispatch hardware interrupts to a user process. The network would have to be dealt with on a packet-by-packet basis, with fragmentation being done by the user of the AM library. Most important, code would have to be written and rewritten for each operating system, networking board, and packet format. Given the plethora of connectivity options available today, an implementation of this type is just not practical.
Another option is to add a new device driver into the kernel. This module could consist of a vector of stub functions referencing a real network device's vector of file operations. A distributed application could then be linked with an AM library that consisted of the AM formatting routines and a few customized kernel traps. Once such a driver was installed, the user would not need to have root privileges to use the network device. Obviously, this situation presents a significant security risk. To overcome such a risk, the AM library and the new driver would have to incorporate some sort of authentication and protection mechanism. All of the problems of the previous approach apply here as well. The difficulty of kernel hacking and widely varying formats for loadable device drivers would further complicate the developer's job. However, it has been shown that this approach can be very successful if the target machines are limited to the same architecture, operating system, and networking interface[15].
The third option in this category of direct device control is to mmap() the network interface into the user's address space. Dealing with the network would require detailed hardware documentation and complete network specifications. Control would be accomplished through register-based operations and could possibly DMA transfers. In addition to having to deal with all the problems of the previous two approaches, the interface would have to be timeshared among multiple processes performing network I/O. Nevertheless, a successful implementation of this approach has been achieved in completely homogeneous environment[9].