Poor man's wireless network

wireless

If you would rather take a longer route to setup your wireless network, instead of the shortcut, rushing to Circuit City to get one wireless AP/router, please tight your seat belt and follow my guidance, and keep it in mind: your miles may vary.

I happen to have one Pentium III Gentoo box as my file server, and one Encore ENLWI-G Wireless G PCI Adapter, how about setup a wireless network for my Dell 700m laptop, so I can surf the web, write blog in the bed?

Proceed with caution

First, we need to find an appropriate driver for this card, as many short-sighted vendors, Marvell does not ship native driver for non-Windows platform, the good news is we have the ndiswrapper to rescue.

For unknown reason, ndiswrapper keeps crashing in gentoo-sources-2.6.17-r8, so I just copy the .config and update the kernel to gentoo-sources-2.6.20-r8, that is proven to be a disastrous decision].

Slow down when crossing the bridge

Bridge seems to make more sense than any other approaches, the Gentoo box would bridge 802.11 wireless network and 802.3 ethernet with the following advantage:

  • Less hassle in the server side: enable 802.1d Ethernet Bridging support in the kernel, and emerge bridge-utils in the userland, done.
  • Transparent to the users: the wireless network is the extension of the ethernet, as if the users are connected to wireless router.

I am following this HOWTO, and here is the sample configuration of /etc/conf.d/net:

bridge_br0=( "eth0" "wlan0")

config_eth0=( null )
config_wlan0=( null )

config_br0=( "192.168.15.144 netmask 255.255.255.0 broadcast 192.168.15.255" )
routes_br0=( "default gw 192.168.15.1" )
depend_br0() {
 need net net.eth0 net.wlan0
}

modules_wlan0=("iwconfig")
mode_wlan0="Ad-hoc"
essid_wlan0="hippo"
channel_wlan0="3"
key_hippo="0123456789"

To have net.wlan0, net.br0 services:

cp /etc/init.d/net.eth0 /etc/init.d/net.wlan0
ln -s /etc/init.d/net.lo /etc/init.d/net.br0
rc-update add net.eth0 default
rc-update add net.wlan0 default
rc-update add net.br0 default

Restart the desktop, in laptop, set the ESSID to hippo with key, then dhcpcd wlan0, try to ping the bridge, then the router. Oops, although we get the correct IP from the top-level ADSL router(192.168.15.1), and get the replay from the bridge, we fail to connect to any other hosts. I have tried different combinations of bridge and netfilter, and eventually found Bridging Mini-HOWTO:

Q: Machines on one side cannot ping the other side!

A: Did you put the interfaces into promiscuous mode? (issue the ifconfig command. The PROMISC flag should be on for both interfaces.)

ndiswrapper does not support promiscuous mode, it is most likely that the incoming packages are not forwarded to the eth0 interface. But how come the dhcpcd works? If you have further explanation, please drop a message in the comment.

Next Services, 240 Miles

NEXT SERVICES, 240 MILES
NEXT SERVICES, 240 MILES

It seems we are going to have a long way to go, if eth0 and wlan0 works individually, we can always use iptables to forward the packages.

Unfortunately, iptables always complained that the kernel is not setup correctly, though I strictly followed The Gentoo Home Router Guide, searched the forums, and found the trick is to start the kernel configuration from the scratch to unleash the hidden options. //sigh

The succeeding setting is quite straightforward, just setup one sub networks in each NIC in the desktop, then use iptables to forward/NAT the packages between the them. Check this post:

# /etc/conf.d/net:
config_eth0=( "192.168.15.133 netmask 255.255.255.0 broadcast 192.168.15.255" )
routes_eth0=( "default via 192.168.15.1" )
dns_servers_eth0=( "192.168.15.1" )

modules_wlan0=("iwconfig")
config_wlan0=("10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255")
mode_wlan0="Ad-hoc"
essid_wlan0="hippo"
adhoc_essid_wlan0="hippo"
channel_wlan0="3"
key_hippo="0123-4567-89 enc open"

Setup the IP forwarding and iptables:

echo "1" > /proc/sys/net/ipv4/ip\_forward # ip\_forward needed in kernel

Setup iptables

iptables -F
iptables -A FORWARD -i eth0 -o wlan0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Serialize the setting in the configuration files:

/etc/init.d/iptables save

Add/uncomment these lines in /etc/sysctl.conf:

net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1

To eliminate the burden of ifconfig/ipconfig, we may run a DHCP relay service in the router, one of lightweight dhcp/dns implementations is dnsmasq. Here is the sample /etc/dnsmasq.conf:

domain-needed
bogus-priv
interface=wlan0
dhcp-range=10.0.0.3,10.0.10,12h

The network architecture is as:

Router
Router

Troubleshooting

[1] The menuconfig is screwed up by the old configuration, to show all the options, it is suggested to configure the kernel from the scratch.

[2] When laptop joins the Ad-hoc wireless network, the desktop may not discover the newcomer, so we have to explicitly set the ESSID of desktop again. I am not quite sure whether this is required by Ad-hoc network or the flaw of the device driver.