Getting Wireless the NDISwrapper Way

Federico Kereki

Issue #164, December 2007

How to make NDISwrapper work with different wireless devices.

Using a wireless connection on Linux still is a dicey thing, and you must acknowledge the fact that you probably will have to go a non-open-source software direction, if you want to have any chance of getting connected. A lot of development is happening in this realm, but let's face it, making wireless devices work natively with open-source drivers is not something you can count on, at least for the time being.

What's the reason for this state of affairs? Just as with graphics cards, there are many factors. Vendors are quite interested in offering newer devices, but the majority of them do not care about Linux and have a Windows-only mindset. Furthermore, if you purchase a laptop, you may not even have the option to choose the card, so you have to make do with whatever you are dealt. Finally, developers cannot produce the needed software when manufacturers won't release the specs, APIs and so on for their products, and this documentation almost never is available.

Thus, unless you are quite lucky and happen to have one of the few open-source-supported options, NDISwrapper probably will be your best option; however, it's no surefire silver bullet. NDISwrapper tries to provide a wrapper around Windows drivers, so Linux can use them as if they were native ones. If you are lucky (okay, not so much lucky, as many drivers seem to work), your Linux machine will think it has perfectly fine drivers and will use them.

Though the program itself is open source, this usage of proprietary drivers is objectionable (maybe even not 100% legal?) and obviously not guaranteed. Furthermore, it's still a bit of a hit-or-miss, not very well documented and somewhat obscure method. There's no fancy graphic interfaces here, only old-fashioned command-line work, with many possibilities for mistakes. Taking all of this into account, it's no wonder many people become conscientious objectors of NDISwrapper or end up not being able to make it work.

Hopefully, in the near future, this will be a moot point, and we will have full open-source software for most, if not all, wireless cards. Certainly, such drivers exist for a select few. In the meantime, we have to make do with this sort of kludge—even though NDISwrapper is brilliant, it's a pity we have to rely on such a program—and wait for better times.

I recently got a somewhat old eMachines M5305 laptop, and as I had to work in a wireless-only office, I had no option but to get wireless going. In this article, I explain how I installed two different kinds of cards (USB and PCI) and got them to function with NDISwrapper. I won't dwell on the many other alternatives I tried (which got me nowhere) and focus on the NDISwrapper solution. Being purely practical, I needed my box to work—open-source software or not.

What Is NDISwrapper?

NDISwrapper stands for Network Driver Interface Spec Wrapper. A wrapper is a technical name for a piece of software that, loosely speaking, allows you to use something in a somewhat different way. Using Windows drivers under Linux certainly qualifies as “using something in a somewhat different way”.

You can find NDISwrapper in most modern distributions. Either use the provided repositories, or go to the NDISwrapper site (see Resources), download the source files and install them yourself. As a matter of fact, even though I use OpenSUSE 10.2 and NDISwrapper was readily available, I opted to go that route myself, so as to get the most up-to-date version. At the time of this writing, the current stable version stands at 1.47, and there is a 1.48RC2 release candidate in the works, but I decided to go with the former.

If you already had a version of NDISwrapper on your system, it might be best to uninstall it first (using the tools in your distribution—I used YaST), and then, as a common user, go to wherever you downloaded the file, and do the following:

tar zxvf ndiswrapper-1.47
cd ndiswrapper-1.47
make distclean
make

Finally, as root, type make install.

First Experiment: the USB Method

I went to a nearby computer shop and found a cheap, nice USB wireless adapter, Allied Telesyn's AT-WCU201G model, which supports speeds up to 108Mbps and is compatible with IEEE 802.11, 802.11b and 802.11g. Of course, today, speeds of 54Mbps are more common, so it's nice having an extra speed reserve resource.

Because this is a USB device, you can use the lsusb command to get the device ID. Insert the device at any USB slot, and do:

lsusb
Bus 003 Device 002: ID 3242:4001
Bus 003 Device 001: ID 0000:0000
Bus 002 Device 001: ID 0000:0000
Bus 001 Device 001: ID 0000:0000

It's pretty clear our device's ID is 3242:4001. If you want more information—there's lots of it—about the device, try lsusb -d 3242:4001 -v, and you can verify the manufacturer, product code, serial number and so on. It's highly likely that other people already will have tried their hands at getting the device to work, so I Googled it on-line to see if there was any help or known good Linux drivers. I didn't find any useful references, but I went on ahead anyway—did you expect to give up so easily?

If you're following along, you will need a Windows XP driver, both the .inf and the .sys files. Fortunately, the product I chose includes a CD with several appropriate drivers, and it's just a matter of copying it to disk. Note that possibly not all Windows drivers will work or be stable. Sometimes you may discover you need to try alternate drivers to get your card to work. Also, the vendor might have included the needed files within an EXE file (try unzipping it and see if you get what you need) or a CAB file.

In my particular case, it was easy—just a matter of copying some files (atiwu.inf and atiwu.sys) and then typing ndiswrapper -i atiwu.inf, followed by ndiswrapper -m and then ndiswrapper -l to list all drivers. I got:

atiwu : driver installed
        device (3242:4001) present

which shows that the device was recognized and the driver was installed. Now, it's time to let Linux know more about the new device. Because I use OpenSUSE, I opened YaST and went to Network Devices→Network Card→Add, and selected the following:

  • Device type: wireless.

  • Configuration name: 0 (so the device will be known as wlan0).

  • Hardware configuration name: static-2 (whatever).

  • Module name: ndiswrapper (most important).

Do not choose PCMCIA or BUS. Then, go through the next screens (pick either DHCP or an IP, specify your DNS servers and so on), until you come to the Wireless Device Settings form. There, you probably will have to set the following:

  • Operating mode: managed (ad hoc would work for a peer-to-peer network).

  • Network name: Guiamovil (the name of the network to which I wanted to connect).

  • Authentication mode: WPA-PSK (open would work for an unrestricted, unprotected, passwordless network).

  • Key input type and encryption key: whatever the network administrator tells you to use. (Of course, you don't need this for an “open” network.)

You can leave all these changes out, however, if you don't know to what network you will be connecting. Simply exit the program, save all the changes, and you will have device wlan0 available. We are almost there!

How Do I Connect?

If you made it this far, you can use the wireless tools, which include iwconfig and iwlist, to configure your device and search for available networks. (Of course, there are many similar tools, some even have graphic interfaces; look around if you so desire.) In my situation, I already knew the network to which I wanted to connect, but in other cases (Wi-Fi hot areas at airports, for example), you would need to look around to find one.

You can scan for networks with iwlist wlan0, and you'll get something like this:

wlan0  Scan completed :
       Cell 01 - Address: 00:16:B6:DB:10:93
                 ESSID:"linksys"
                 Protocol:IEEE 802.11g
                 Mode:Managed
                 Frequency:2.437 GHz (Channel 6)
                 Quality:0/100 Signal level:-84 dBm Noise level:-256 dBm
                 Encryption key:off
                 Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 18 Mb/s
                          24 Mb/s; 36 Mb/s; 54 Mb/s; 6 Mb/s; 9 Mb/s
                          12 Mb/s; 48 Mb/s
                 Extra:bcn_int=100
                 Extra:atim=0
       Cell 02 - Address: 00:4F:67:00:C1:AA
                 ESSID:"Guiamovil"
                 Protocol:IEEE 802.11g
                 Mode:Managed
                 Frequency:2.437 GHz (Channel 6)
                 Quality:0/100 Signal level:-67 dBm Noise level:-256 dBm
                 Encryption key:on
                 Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 6 Mb/s
                           9 Mb/s; 12 Mb/s; 18 Mb/s; 24 Mb/s; 36 Mb/s
                           48 Mb/s; 54 Mb/s
                 Extra:bcn_int=200
                 Extra:atim=0
                 IE: WPA Version 1
                     Group Cipher : WEP-40
                     Pairwise Ciphers (1) : WEP-40
                     Authentication Suites (1) : PSK

Great, the connection I wanted is there (the second one, Guiamovil), and also another open, unprotected one called Linksys. (The unchanged name is a giveaway that the wireless router was installed without any specific configuration.)

If you would rather use the command line, iwconfig allows configuring the wireless device. Try iwconfig --help or man iwconfig to learn more about this. For example, I could get the same results that I did with YaST by typing:

iwconfig wlan0 essid "Guiamovil" mode managed key 
"s:THESECRETPASSWORD" commit

Now, you simply can ping any site to check how the device is working or connect to the Web and surf along.

Second Experiment: the PCMCIA Method

A friend of mine loaned me a PCMCIA card, so I could test a different kind of device. I first thought about removing the USB driver and setup and then installing his card, but that would have been sort of lame. Anyway, just to make sure the card worked, I tried it, starting with:

ndiswrapper -r atiwu
rm /etc/modprobe.d/ndiswrapper
cd /path.where.you.downloaded.ndiswrapper
make uninstall
make clear
make
make install

to get back to square zero. I then inserted the card into its slot and used the lspci and lspci -v commands to learn more about it. I found the card at the bottom of the listing, and the second command produced its ID (11ab:1faa):

$ lspci
00:00.0 Host bridge: ATI Technologies Inc AGP Bridge 
                     [IGP 320M] (rev 13)
00:01.0 PCI bridge: ATI Technologies Inc PCI Bridge 
                    [IGP 320M] (rev 01)
00:07.0 ISA bridge: ALi Corporation M1533/M1535 PCI to 
                    ISA Bridge [Aladdin IV/V/V+]
00:08.0 Multimedia audio controller: ALi Corporation M5451 
          PCI AC-Link Controller Audio Device (rev 02)
00:09.0 Modem: ALi Corporation M5457 AC'97 Modem Controller
00:0a.0 CardBus bridge: ENE Technology Inc CB1410 Cardbus Controller
00:0d.0 USB Controller: NEC Corporation USB (rev 43)
00:0d.1 USB Controller: NEC Corporation USB (rev 43)
00:0d.2 USB Controller: NEC Corporation USB 2.0 (rev 04)
00:0e.0 Ethernet controller: Broadcom Corporation BCM4401 
                             100Base-T (rev 01)
00:10.0 IDE interface: ALi Corporation M5229 IDE (rev c4)
00:11.0 Bridge: ALi Corporation M7101 Power 
                Management Controller [PMU]
01:05.0 VGA compatible controller: ATI Technologies Inc 
                                   Radeon Mobility U1
02:00.0 Ethernet controller: Marvell Technology Group Ltd. 
              88w8335 [Libertas] 802.11b/g Wireless (rev 03)
$ lspci -s 02:00.0 -v
02:00.0 Class 0200: 11ab:1faa (rev 03)

This time, Googling for 11ab:1faa was lucky. I found several references saying that the card worked well, so I went ahead and installed it using the same method as with the USB card. It worked just fine—it was almost anticlimactic.

Now, back to the original idea of installing both devices at the same time. I wasn't even sure if NDISwrapper could handle two drivers at the same time, and when I searched the Web, I found nothing. Plowing ahead, I decided to experiment a bit. It turns out that the /etc/modprobe.d/ndiswrapper file read:

alias wlan0 ndiswrapper

So, I added an alias wlan1 ndiswrapper line to it, just to see if it made any difference. I went back to the beginning (uninstalled everything), rebooted (just in case) and started again. After setting up both devices, I tried iwconfig and happily saw that both interfaces were recognized. I could remove either of them, and the other still worked fine. I noted that the Allied Telesyn USB device was more sensitive—it could find more remote networks—than the Netgear card, but I guess that's reasonable, as the former is newer and could be expected to be more potent.

Conclusion

Even though wireless devices are still a low point for Linux, using NDISwrapper provides a good solution, if you are not dogmatic about proprietary binary drivers or using Windows software on your Linux box. I would prefer an OSS solution, but I can't wait for it. There are no guarantees, of course, but my experiments convinced me that getting wireless to work should be an easy job, and I was able to make two different devices work at the same time, which attests to the quality of NDISwrapper.

Federico Kereki is an Uruguayan Systems Engineer, with more than 20 years' experience teaching at universities, doing development and consulting work, and writing articles and course material. He has been using Linux for many years now, having installed it at several different companies. He is particularly interested in the better security and performance of Linux boxes.