NEmu

Network Emulator for Mobile Universes

Documentation - Writing a new VRouter Service

NEmu provides a plugin system wich allows you to easily add new services for virtual routers. All NEmu services are stored in {NEMUROOT}/nemu/vrs/. Please not that you can put a service directory outside {NEMUROOT}/nemu/vrs/ (please refer to the VRouter section to learn how to use it).

A service is represented by a directory of the same name:

{service name}/
|-- __init__.py  # Service source file
|-- tcz/         # Service TCZ packages (32 bits) [Optional]
|-- files/       # Service user files [Optional]

Virtual routers are running on a custom version of the Linux distribution TinyCore which uses TCZ packages. If you need to use a certain package in order to add a new service, please include package files (in 32 bits) from the TCZ official lists here and here. Files contained in the files directory will be copied at the root of the virtual router at startup.

The python script __init__.py has to comply with the following architecture:

from nemu.vrc import VRc

def init(vrouter, *largs, **kargs):
  fd = VRc(name={name}, id={id}, vrouter=vrouter, mode={mode})
  fd.close()

def help():
  ret = dict()
  ret['syn'] = 'Service({service name}, {arguments...})'
  ret['desc'] = {Service Description}
  ret['args'] = list()
  ret['args'].append({description of the first argument})
  ret['args'].append({description of the second argument})
  # ...
  return ret

The init function is the core of your plugin where you have to write the python execution code which will be executed by the NEmu interpreter. A Service is the way to generate an executable file (or script) which will be executed by the virtual router itself at startup. The VRc function generated the executable file with the name name and the execution order id with file open mode mode. You can generated several VRc in a same service. The help function is the text which will be displayed by the ListService NEmu function.

For instance, here is the implementation of the service command which allows the user to execute some various ash shell commands:

from nemu.vrc import VRc

def init(vrouter, *largs, **kargs):
  fd = VRc(name='self_command', id=str(kargs[int(id)]), 
                                  vrouter=vrouter, mode='a+')
  for line in largs:
      fd.write(str(line))
  fd.close()

def help():
  ret = dict()
  ret['syn'] = 'Service("command", ... , id)'
  ret['desc'] = 'Shell commands to execute at startup'
  ret['args'] = list()
  ret['args'].append('[list of strings] : commands list')
  ret['args'].append('id [int] : ID of the generated script')
  return ret

Here is another example which requires additional TCZ packages: the implementation of the service httpd which allows the user to launch a HTTP Daemon at startup:

# The HTTPD Service directory

httpd/
|-- __init__.py
|-- tcz/
|   |-- busybox-httpd.tcz
|   |-- busybox-httpd.tcz.info
|   |-- busybox-httpd.tcz.list
|   |-- busybox-httpd.tcz.md5.txt
|   |-- busybox-httpd.tcz.tree
`   `-- busybox-httpd.tcz.zsync
# The __init__.py script

import os
from nemu.vrc import VRc

def init(vrouter, *largs, **kargs):
  fd = VRc(name='httpd_root', id='00', vrouter=vrouter)
  fd.write('touch /etc/httpd.conf;')
  fd.write('echo \'A:*\' > /etc/httpd.conf;')
  fd.close()
    
  fd = VRc(name='httpd_conf', id='02', vrouter=vrouter, mode='a+')
  root = str(kargs['root'])
  port = 80
  if 'port' in kargs:
      port = int(kargs['port'])
  fd.write('/usr/local/httpd/sbin/httpd -c /etc/httpd.conf -h ' 
           + root + ' -p ' + str(port))
  fd.close()

def help():
  ret = dict()
  ret['syn'] = 'Service("httpd", root, port)'
  ret['desc'] = 'Starts a HTTPD server daemon at startup'
  ret['args'] = list()
  ret['args'].append('root [string] : server root directory')
  ret['args'].append('port [int] : server listening port (80)')
  return ret