ImageFlasher was a 2011 Google Summer of Code project bridging a gap between firmware images generated by nodewatcher and flashing them on devices. This last step is often much too technical than needed and represents a barrier for users. ImageFlasher solves this by providing a simple to use graphical user interface wizard supporting a wide range of routers.
The application has to be cross-platform. That is one of the major goals of the project. The design of the project follows. Please e-mail any improvements or criticism to dev mailing list.
The network stack
The lwIP network stack will be ported to libpcap. Initially, we were considering uIP vs lwIP. But because the flashing will be carried out by decently strong machines, it makes sense to go with lwIP. uIP is designed for an environment with very stringent resource constraints. lwIP on the other hand requires more resources and shows equal, if not exponential, improvement in terms of performance. We require atleast the following features from the network stack:
lwIP supports all of these and more. Further, lwIP has very good documentation. There is also lwIP platform developer's manual which is quite invaluable for our work. The code also is very modular which makes porting easier. There is also the complete report on lwIP written by the Adam Dunkels. All these reasons, point to lwIP being a perfect choice.
lwIP is a complete network stack. As such we would expect it to depend for a lot of functionality, on the operating system on which it is running. But the way operating system offers this functionality differs between operating systems. Specifically, the functionality we require is
- Threads (operational)
- Architecture dependent constants
So, this functionality has to be abstracted to the actual core of the lwIP stack under a common interface. Fortunately, the design of this interface has already been done while building the lwIP stack. All the operating system dependent details are implemented as a separate "OS Abstraction layer" within the lwIP stack. That makes our work clean. We need to abstract the above functionality from each operating system within that layer.
Then why libpcap? Initially, We were thinking of using raw sockets. But slowly, the option got ruled out. Raw sockets don't recieve TCP/UDP datagrams because the UNIX kernel processes these and doesn't post a copy to the waiting raw sockets. So, We have to use datalink access to recieve all the network traffic and then filter that to pass on only the necessary packets to the above network stack. There are four different ways to gain datalink access. They are:
- BPF Berkeley packet filter
- DLPI Datalink Provider Interface
- PF_PACKET,SOCK_PACKET with socket()
BPF is supported on some of the UNIX kernels, like the FreeBSD. Similarly DLPI is also limited. The socket() options only work under Linux. The ap51-flash-ng was written for linux. It used this model. This model not only is incompatible with other Unix kernels, but is also some-what inefficient and shows a considerable lag in high traffic networks. Anyhow, none of these work with Microsoft Windows. Extensive raw socket support was removed from Windows after 2000. The accepted way for datalink access in windows currently is using Winpcap. Winpcap bypasses the normal network access in the operating system by installing a separate networking driver. This driver provides access to the datalink. Winpcap is a mod of the libpcap written for Unix based kernels. So, libpcap is an abstraction over the above three access mechanisms. Still libpcap also has some minor platform dependencies, but these can be ignored.
That done, the next step is to interface the lwIP stack with libpcap. lwIP stack uses the device driver of a network interface to have completely raw access to the datalink. What we need to do is, write a device driver for lwIP that projects the libpcap as a network interface to the lwIP stack. libpcap has all the properties a network interface should have. That is because, it borrows those properties from the network device that it opens. So, the driver should pass on the details of the device that libpcap selects as the details of the libpcap interface to lwIP stack.
The design of the application layer of the flasher follows. Any missing details will be updated. The design mainly focuses on the following:
- 'Step'-by-step approach to flashing
- Easy addition of new router types with as little change as possible
- Complete UI (Console vs GUI) abstraction to the actual flasher
The entire flashing process is divided into 'n' number of steps.
5-n. Flashwizard(Multiple number of steps depending upon the router type)
Every step is subclass of the abstract class Step.
While adding support for new routers, the steps required to flash that specific router are to be implemented as subclasses. But to define a step, the UI should also be accessed. Instead of directly accessing specific UI components, the UI layer is abstracted by the 'UI' class. The underlying implementation of this class decides whether flasher is GUI based or console based. The main advantages of such an abstraction is that the core functionality of the flasher would work with any interface which is implemented. If the GUI library isn't working well, it can be replaced by another without any change to the core functionality. Just the UI class would have to be re-implemented. Some layout steps are provided, which can be extended to use the functionality of that layout.
The functionality to the flasher like TFTP server, client, telnet would be implemented as classes so that for adding support to new routers also these classes can be reused as required. The design for the functionality is not yet completely ready. It will be improved as the work progresses.
This document reflects the current design idea.It will be revised as the work progresses.
This program is open source, under GNU General Public License.
Any additional content is available under Creative Commons Attribution-ShareAlike license unless specified otherwise.
Developed source code may contain, use, link to and/or distribute also parts under third party copyright with possibly different licensing conditions. Make sure you check and respect also those conditions.
For more information and more precise licensing requirements, see LICENSE file in the source code repository.