Poor man’s wireless network

Gentoo, Network May 28th, 2007

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?

Drive it 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[1].

Slow down, acrossing 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[2], 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

It seems we are going to have a long way to go, if eth0 and wlan0 works solely, 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:
# turn on forwarding
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


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.

Zen is less Creative in software

Gentoo May 25th, 2007

I have been allured by the Creative ZenMicro for its relative high-finite sound quality and cost efficiency, last but not the least, the free PlayForSure DRM WMA service provided by Arlington County library. Eventually, I got a refurbished white Creative ZenMicro.

It works as a charm with Amarok in my Gentoo Linux, you even don’t bother to rebuild the kernel since libnjb works in the user land. Still two things bother me: the Chinese Id3v2 tag support and MTP support. After checking their web site, I start the nightmare to upgrade the firmware.

According to their knowledge base, the firmware upgrade utility only works on Windows XP with SP1 and explicitly Windows Media Player 10. What the hell of this? Does Creative Lab have a special promotion for Windows XP sale? Unfortunately, I have one Windows Vista Business and one Windows 2000 Professional. I downloaded almost 100M software and install them in my two Windows platform, failed, fair enough. I just wondered how the Windows user could stand such a bloated software just for music transfer.

Thanks for my roommate, he has one Windows XP Home, one Windows XP Professional as the playgrounds. Unfortunately, the firmware upgrade still failed without any error message, the application just hang there, no response. I eventually call the Creative Labs. The reception felt sorry about my situation, and offered me to replace the device if I would like to pay the shipping, round trip, via either FedEx or UPS. And she was so kind to remind me I should do this ASAP in the one month’s warranty.

What a crappy company!

UPDATE: Creative refund the full price with tax at the end since Creative ZenMicro is out of stock.

C++ Study Note(2): Cast the light to the darkness

Development May 23rd, 2007

The old-school C casting is reckless without type checking, to make it worse, the casting is easily overlooked by the maintainers. C++ introduces four cast keywords to rescue: const_cast, static_cast, dynamic_cast, and reinterpret_cast.

The keyword const is a contract between the library developers and users. Dropping the const decorator may incur unexpected behavior, for example:

class Foo
{
public:
        Foo() : dd(0) {}
        // int& bar() { cout << "non-const " << dd << endl; return dd; }
        const int& bar() const { cout << "const " << dd << endl;  return dd; }
private:
        int dd;
};

… …
        Foo foo;
        int & x = const_cast<int&>(foo.bar());
        x = 3;

C++ impose the developers to use const_cast to highlight the action, “Warning, warning, the const decoration is dropped…”, the same reason lies in the bool type.

If you are quite confident the type downcasting, static_cast is the right option for you. The compiler would adjust the offset and return a derived class pointer for you in the compile time, aka free overhead. If you could not guarantee the heritage, use dynamic_cast, the runtime would try to down cast the pointer/reference and return a valid pointer/reference if everything is OK, otherwise, a null pointer is returned for pointer down-casting, or a bad_cast exception is raised for the reference casting.

Update: Boost‘s developers dislike the inconsistence, a new cast template function, polymorph_cast is introduced for the downcasting and crosscasting:

template <class Target, class Source>
    inline Target polymorphic_cast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
    {
        Target tmp = dynamic_cast<Target>(x);
        if ( tmp == 0 ) throw std::bad_cast();
        return tmp;
    }

It helps the careless developers to test the validity of the returned pointer, throw an exception if necessary.

If you would like both the type safety from dynamic_cast, and also the performance of static_cast, Boost has another neat cast function, polymorphic_downcast for you such a greedy jerk.

template <class Target, class Source>
    inline Target polymorphic_downcast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
    {
        BOOST_ASSERT( dynamic_cast<Target>(x) == x );  // detect logic error
        return static_cast<Target>(x);
    }

This cast only works on downcast the pointer, you can tell from the name; it does dynamic_cast in the debug version and static_cast in the release version.

Last and the least, reinterpret_cast, the compiler would just simply pretend the object has a new type without any validation check, offset adjustment; furthermore, it is NOT portable. Use it in caution and make sure you know clearly what you are doing.

Sanitize the kernel, Bye-bye Cisco VPN

Gentoo, Network May 22nd, 2007

I’ve been using Cisco VPN client to access GWireless and Penn State Wireless for quite a long time since I managed to get it work. Two things bother me, the notice in dmesg

cisco_ipsec: module license ‘Proprietary’ taints kernel.

and that the Cisco VPN client stops working after a period inactivity. It fails to connect the Virtual Adapter once it disconnects, I have to restart the machine to get it work again.

Here is an alternative application vpnc in the portage. Before we move to the next step, we need enable Device Drivers | Network device support | Universal TUN/TAP device driver support in Linux kernel. David Ramsden hacked a script to convert the Cisco VPN Client’s profile to vpnc configuration file. Copy the converted conf to /etc/vpnc/default.conf and start the vpnc service. Done.

Current /etc/init.d/vpnc does not support profiles, I might hack a patch to cope with this problem later.

dojo.gfx 3d proof-of-concept implementation

Web May 19th, 2007

This is the first proof-of-concept implementation of dojo.gfx 3d support. Just copy test3d.html to $dojo/trunk/tests/gfx/, and launch any SVG-based browser, Mozilla Firefox is preferred, and you would found a cube like this:

Cube SVG



This is a quite quick-n-dirty implementation, the Path3d class is more or less a hybrid of dojo.gfx.Path and dojo.gfx.path.Path, operations are copied from here and there with modification to meet our needs. The main contribution of this test is

  • Test case itself, we may use the same interface to manipulate the 3D objects
  • cameraTransform, the mapping of 3D space to 2D surface

We are probably inspired by this lousy implementation for its weakness:

  • Separate the 3D and 2D domain – this is essential since we want to reuse the interface as much as possible, for example, 3D space’s path syntax is the same as 2D’s with different number of arguments.
  • Move shared functions to infrastructure layer, then we can reuse it in both 2D and 3D domains
  • Move the matrix operation to dojo.gfx.matrix.3d namespace
  • Attach more meta data to the SVG DOM node, for example, original (x, y, z) path, transform, x, y, z axis’s rotation, scaling matrix for further transformation. CAUTION: this is quite computation extensive
  • Attach – this could be a big problem. When attaching a dojo.gfx object to existed SVG node, we need to differentiate the domains by using the meta data mentioned above.

I think I need to consult with my mentor for more details about refactoring.