Thursday 22 December 2016

Friday 9 December 2016

Implementing a Custom DHCP Server (with customizable DHCP Router IP field) on Windows CE on Wi-Fi adhoc connection

Recently, we had a requirement from a customer:
1. Our Windows CE device must be able to host an adhoc network.
2. It must have a DHCP server and it must provide a Router IP of 0.0.0.0 to the client (iPhone or iPad).


Adhoc Network on Windows CE

Luckily, Windows CE can do Adhoc Network connection. An iPhone can connect to it. However, whenever we connect a USB WIFI dongle, we always get a UI for setting up Wifi connection. The way to suppress this is by disabling it on the Platform Builder.

Second, the quickest way to establish an Adhoc connection programatically is by using the open-source OpenNetCF library. But since we are using a NET CF 2.0 device, I ported the OpenNetCF from 3.5 down to 2.0. It works very well.


DHCP Server with Router IP 0.0.0.0


The reason why our customer needs 0.0.0.0 is because it must be able to connect to 3G while Adhoc is connected and this is the only known way to do that.

At first, we used the built in DHCP allocator of Windows CE but it doesn't return Router IP of 0.0.0.0 no matter what we do (or maybe there are some registry settings that we missed). But the problem is the source code for this is not available.

What I did is I implemented a DHCP server on Windows CE. There is a desktop C# DHCP server that I saw on CodeProject. I ported it to .NET CF 2.0 and it works. I can now modify the packets. I can now set the Router IP to 0.0.0.0.  BUT... the DHCP works only if the ActiveSync cable is connected. This is how I was able to solve it:

I did some investigation using WireShark and I can see that UDP/DHCP packets are not being sent when ActiveSync cable is not connected. On the file clsUdpAsync.cs, the function public void SendData(byte[] Data)  will send a SocketException error regarding DNS whenever the ActiveSync cable is not connected. Digging further, I noticed that there are overloaded BeginSend function on UdpClient class. One of the functions has the parameter hostname and whenever we call that, it requires some NS resolution even if your input to the function is "255.255.255.255" which is a broadcast address. One function has a parameter IPEndPoint and just require IPAddress object. I used that and everything worked perfectly.

I forked it, rectified the SendData function and placed it on my Github account. Link