From 02f1617c003592f6af2407cfdf9f85a862a98fdf Mon Sep 17 00:00:00 2001
From: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
Date: Wed, 20 Aug 2014 12:39:45 +0200
Subject: [PATCH] ibrdtnd: add new package

This package contains the daemon (dtnd) of IBR-DTN, a modular and lightweight
implementation of the bundle protocol (RFC 5050). https://github.com/ibrdtn/ibrdtn

Signed-off-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
---
 net/ibrdtnd/Makefile                |  58 +++++++++
 net/ibrdtnd/files/build-config.sh   | 168 ++++++++++++++++++++++++++
 net/ibrdtnd/files/ibrdtn.init       |  71 +++++++++++
 net/ibrdtnd/files/ibrdtn.uci        | 175 ++++++++++++++++++++++++++++
 net/ibrdtnd/files/mkcontainer.sh    |  43 +++++++
 net/ibrdtnd/files/mountcontainer.sh | 122 +++++++++++++++++++
 net/ibrdtnd/files/safety-wrapper.sh | 172 +++++++++++++++++++++++++++
 net/ibrdtnd/files/systemcheck.sh    | 101 ++++++++++++++++
 8 files changed, 910 insertions(+)
 create mode 100644 net/ibrdtnd/Makefile
 create mode 100644 net/ibrdtnd/files/build-config.sh
 create mode 100644 net/ibrdtnd/files/ibrdtn.init
 create mode 100644 net/ibrdtnd/files/ibrdtn.uci
 create mode 100644 net/ibrdtnd/files/mkcontainer.sh
 create mode 100644 net/ibrdtnd/files/mountcontainer.sh
 create mode 100644 net/ibrdtnd/files/safety-wrapper.sh
 create mode 100644 net/ibrdtnd/files/systemcheck.sh

diff --git a/net/ibrdtnd/Makefile b/net/ibrdtnd/Makefile
new file mode 100644
index 000000000..72d58b1ce
--- /dev/null
+++ b/net/ibrdtnd/Makefile
@@ -0,0 +1,58 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ibrdtnd
+PKG_VERSION:=0.12.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.ibr.cs.tu-bs.de/projects/ibr-dtn/releases
+PKG_MD5SUM:=8dad5ebbcfaa4c16ba151c9c289066c3
+PKG_MAINTAINER:=Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
+PKG_LICENSE:=Apache-2.0
+
+PKG_INSTALL:=1
+PKG_BUILD_DEPENDS:=dtndht ibrdtn libsqlite3
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ibrdtnd
+  SECTION:=net
+  CATEGORY:=Network
+  DEPENDS:=+dtndht +ibrdtn +libsqlite3
+  TITLE:=DTN Deamon
+endef
+
+define Package/ibrdtnd/conffiles
+/etc/config/ibrdtn
+endef
+
+define Package/ibrdtnd/description
+ The implementation of the bundle protocol of the IBR (TU Braunschweig).
+endef
+
+CONFIGURE_ARGS += \
+        --with-tls --with-sqlite --with-dht
+
+define Package/ibrdtnd/install
+	$(INSTALL_DIR) $(1)/usr/sbin/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/dtnd $(1)/usr/sbin/
+	$(INSTALL_BIN) files/safety-wrapper.sh $(1)/usr/sbin/dtnd-safety-wrapper.sh
+	$(INSTALL_DIR) $(1)/usr/share/ibrdtn/
+	$(INSTALL_BIN) files/build-config.sh $(1)/usr/share/ibrdtn/build-config.sh
+	$(INSTALL_BIN) files/mkcontainer.sh $(1)/usr/share/ibrdtn/mkcontainer.sh
+	$(INSTALL_BIN) files/mountcontainer.sh $(1)/usr/share/ibrdtn/mountcontainer.sh
+	$(INSTALL_BIN) files/systemcheck.sh $(1)/usr/share/ibrdtn/systemcheck.sh
+	$(INSTALL_DIR) $(1)/etc/init.d/
+	$(INSTALL_BIN) files/ibrdtn.init $(1)/etc/init.d/ibrdtn
+	$(INSTALL_DIR) $(1)/etc/config
+	$(INSTALL_CONF) files/ibrdtn.uci $(1)/etc/config/ibrdtn
+endef
+
+$(eval $(call BuildPackage,ibrdtnd))
diff --git a/net/ibrdtnd/files/build-config.sh b/net/ibrdtnd/files/build-config.sh
new file mode 100644
index 000000000..82f161cc5
--- /dev/null
+++ b/net/ibrdtnd/files/build-config.sh
@@ -0,0 +1,168 @@
+#!/bin/sh
+#
+# convert uci configuration into daemon specific format
+#
+
+UCI=/sbin/uci
+
+create_file() {
+	echo "# -- DO NOT EDIT THIS FILE --" > $1
+	echo "# automatic generated configuration file for IBR-DTN daemon" >> $1
+	echo "#" >> $1
+}
+
+add_param() {
+	VALUE=`$UCI -q get $2`
+	
+	if [ $? == 0 ]; then
+		echo "$3 = $VALUE" >> $1
+	fi
+}
+
+getconfig() {
+	$UCI -q get ibrdtn.$1
+	return $?
+}
+
+if [ "$1" == "--safe-mode" ]; then
+	SAFEMODE=yes
+	CONFFILE=$2
+else
+	SAFEMODE=no
+	CONFFILE=$1
+fi
+
+# create the file and write some header info
+create_file $CONFFILE
+
+add_param $CONFFILE "ibrdtn.main.uri" "local_uri"
+add_param $CONFFILE "ibrdtn.main.routing" "routing"
+add_param $CONFFILE "ibrdtn.main.fragmentation" "fragmentation"
+
+if [ "$SAFEMODE" == "yes" ]; then
+	if [ -n "`getconfig safemode.forwarding`" ]; then
+		add_param $CONFFILE "ibrdtn.safemode.forwarding" "routing_forwarding"
+	else
+		add_param $CONFFILE "ibrdtn.main.forwarding" "routing_forwarding"
+	fi
+
+	if [ -n "`getconfig safemode.maxblock`" ]; then
+		add_param $CONFFILE "ibrdtn.safemode.maxblock" "limit_blocksize"
+	else
+		add_param $CONFFILE "ibrdtn.main.blocksize" "limit_blocksize"
+	fi
+
+	if [ -n "`getconfig safemode.storage`" ]; then
+		add_param $CONFFILE "ibrdtn.safemode.storage" "limit_storage"
+	else
+		add_param $CONFFILE "ibrdtn.storage.limit" "limit_storage"
+	fi
+else
+	add_param $CONFFILE "ibrdtn.main.forwarding" "routing_forwarding"
+	add_param $CONFFILE "ibrdtn.main.blocksize" "limit_blocksize"
+	add_param $CONFFILE "ibrdtn.storage.limit" "limit_storage"
+	add_param $CONFFILE "ibrdtn.storage.blobs" "blob_path"
+	add_param $CONFFILE "ibrdtn.storage.bundles" "storage_path"
+	add_param $CONFFILE "ibrdtn.storage.engine" "storage"
+fi
+
+add_param $CONFFILE "ibrdtn.main.max_predated_timestamp" "limit_predated_timestamp"
+add_param $CONFFILE "ibrdtn.main.limit_lifetime" "limit_lifetime"
+add_param $CONFFILE "ibrdtn.main.foreign_blocksize" "limit_foreign_blocksize"
+
+add_param $CONFFILE "ibrdtn.discovery.address" "discovery_address"
+add_param $CONFFILE "ibrdtn.discovery.timeout" "discovery_timeout"
+add_param $CONFFILE "ibrdtn.discovery.version" "discovery_version"
+add_param $CONFFILE "ibrdtn.discovery.crosslayer" "discovery_crosslayer"
+
+add_param $CONFFILE "ibrdtn.tcptuning.idle_timeout" "tcp_idle_timeout"
+add_param $CONFFILE "ibrdtn.tcptuning.nodelay" "tcp_nodelay"
+add_param $CONFFILE "ibrdtn.tcptuning.chunksize" "tcp_chunksize"
+
+add_param $CONFFILE "ibrdtn.security.level" "security_level"
+add_param $CONFFILE "ibrdtn.security.bab_key" "security_bab_default_key"
+add_param $CONFFILE "ibrdtn.security.key_path" "security_path"
+add_param $CONFFILE "ibrdtn.security.generate_dh" "generate_dh_params"
+
+add_param $CONFFILE "ibrdtn.tls.certificate" "security_certificate"
+add_param $CONFFILE "ibrdtn.tls.key" "security_key"
+add_param $CONFFILE "ibrdtn.tls.trustedpath" "security_trusted_ca_path"
+add_param $CONFFILE "ibrdtn.tls.required" "security_tls_required"
+add_param $CONFFILE "ibrdtn.tls.noencryption" "security_tls_disable_encryption"
+add_param $CONFFILE "ibrdtn.tls.fallback_badclock" "security_tls_fallback_badclock"
+
+add_param $CONFFILE "ibrdtn.timesync.reference" "time_reference"
+add_param $CONFFILE "ibrdtn.timesync.synchronize" "time_synchronize"
+add_param $CONFFILE "ibrdtn.timesync.discovery_announcement" "time_discovery_announcements"
+add_param $CONFFILE "ibrdtn.timesync.sigma" "time_sigma"
+add_param $CONFFILE "ibrdtn.timesync.psi" "time_psi"
+add_param $CONFFILE "ibrdtn.timesync.sync_level" "time_sync_level"
+add_param $CONFFILE "ibrdtn.timesync.time_set_clock" "time_set_clock"
+
+add_param $CONFFILE "ibrdtn.dht.enabled" "dht_enabled"
+add_param $CONFFILE "ibrdtn.dht.port" "dht_port"
+add_param $CONFFILE "ibrdtn.dht.id" "dht_id"
+add_param $CONFFILE "ibrdtn.dht.bootstrap" "dht_bootstrapping"
+add_param $CONFFILE "ibrdtn.dht.nodesfile" "dht_nodes_file"
+add_param $CONFFILE "ibrdtn.dht.enable_ipv4" "dht_enable_ipv4"
+add_param $CONFFILE "ibrdtn.dht.enable_ipv6" "dht_enable_ipv6"
+add_param $CONFFILE "ibrdtn.dht.bind_ipv4" "dht_bind_ipv4"
+add_param $CONFFILE "ibrdtn.dht.bind_ipv6" "dht_bind_ipv6"
+add_param $CONFFILE "ibrdtn.dht.ignore_neighbour_informations" "dht_ignore_neighbour_informations"
+add_param $CONFFILE "ibrdtn.dht.allow_neighbours_to_announce_me" "dht_allow_neighbours_to_announce_me"
+add_param $CONFFILE "ibrdtn.dht.allow_neighbour_announcement" "dht_allow_neighbour_announcement"
+
+
+# iterate through all network interfaces
+iter=0
+netinterfaces=
+while [ 1 == 1 ]; do
+	$UCI -q get "ibrdtn.@network[$iter]" > /dev/null
+	if [ $? == 0 ]; then
+		netinterfaces="${netinterfaces} lan${iter}"
+		add_param $CONFFILE "ibrdtn.@network[$iter].type" "net_lan${iter}_type"
+		add_param $CONFFILE "ibrdtn.@network[$iter].interface" "net_lan${iter}_interface"
+		add_param $CONFFILE "ibrdtn.@network[$iter].port" "net_lan${iter}_port"
+	else
+		break
+	fi
+	
+	let iter=iter+1
+done
+
+# write list of network interfaces
+echo "net_interfaces =$netinterfaces" >> $CONFFILE
+
+# iterate through all static routes
+iter=0
+while [ 1 == 1 ]; do
+	$UCI -q get "ibrdtn.@static-route[$iter]" > /dev/null
+	if [ $? == 0 ]; then
+		PATTERN=`$UCI -q get "ibrdtn.@static-route[$iter].pattern"`
+		DESTINATION=`$UCI -q get "ibrdtn.@static-route[$iter].destination"`
+		let NUMBER=iter+1
+		echo "route$NUMBER = $PATTERN $DESTINATION" >> $CONFFILE
+	else
+		break
+	fi
+	
+	let iter=iter+1
+done
+
+#iterate through all static connections
+iter=0
+while [ 1 == 1 ]; do
+	$UCI -q get "ibrdtn.@static-connection[$iter]" > /dev/null
+	if [ $? == 0 ]; then
+		let NUMBER=iter+1
+		add_param $CONFFILE "ibrdtn.@static-connection[$iter].uri" "static${NUMBER}_uri"
+		add_param $CONFFILE "ibrdtn.@static-connection[$iter].address" "static${NUMBER}_address"
+		add_param $CONFFILE "ibrdtn.@static-connection[$iter].port" "static${NUMBER}_port"
+		add_param $CONFFILE "ibrdtn.@static-connection[$iter].protocol" "static${NUMBER}_proto"
+		add_param $CONFFILE "ibrdtn.@static-connection[$iter].immediately" "static${NUMBER}_immediately"
+	else
+		break
+	fi
+	
+	let iter=iter+1
+done
diff --git a/net/ibrdtnd/files/ibrdtn.init b/net/ibrdtnd/files/ibrdtn.init
new file mode 100644
index 000000000..5a00c2411
--- /dev/null
+++ b/net/ibrdtnd/files/ibrdtn.init
@@ -0,0 +1,71 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2007 OpenWrt.org
+
+START=90
+
+start() {
+	# check if the daemon is disabled
+	if [ "`/sbin/uci -P/var/state -q get ibrdtn.disable`" == "1" ]; then
+		/bin/echo "dtnd is disabled"
+		return
+	fi
+	
+	/bin/echo -n "running dtnd ..."
+	
+	# startup the safety-wrapper for the daemon
+	/usr/sbin/dtnd-safety-wrapper.sh &
+	
+	# store the pid of the process in uci states
+	/sbin/uci -P/var/state -q set ibrdtn.safetypid=`echo $!`
+	
+	/bin/echo " done"
+}
+
+stop() { 
+	# check if the daemon is disabled
+	if [ "`/sbin/uci -P/var/state -q get ibrdtn.disable`" == "1" ]; then
+		/bin/echo "dtnd is disabled"
+		return
+	fi
+	
+	/bin/echo -n "stopping dtnd ..."
+	
+	# set state to None, this indicates a clear shutdown to the safety-wrapper.
+	/sbin/uci -P/var/state -q set ibrdtn.state=None
+	
+	# stop the safety-wrapper
+	if [ -n "`/sbin/uci -P/var/state -q get ibrdtn.safetypid`" ]; then
+		/usr/bin/kill `/sbin/uci -P/var/state -q get ibrdtn.safetypid` 2> /dev/null >/dev/null
+	fi
+	
+	# finally kill really all safety-wrapper!
+	/bin/sleep 2
+	/usr/bin/killall -9 dtnd-safety-wrapper.sh
+	
+	# send a kill signal to the daemon
+	/usr/bin/killall dtnd 2> /dev/null >/dev/null
+	
+	# wait for some time
+	TIMEOUT=0;
+	
+	# check if the daemon is running
+	while [ -n "`ps | grep dtnd | grep -v grep`" ]; do
+		# check if the daemon is still running
+		if [ $TIMEOUT -ge 10 ]; then
+			/bin/echo " killing"
+			# kill all processes of dtnd
+			/usr/bin/killall -9 dtnd 2> /dev/null >/dev/null
+			return
+		fi
+		
+		# increment timeout
+		TIMEOUT=`expr $TIMEOUT + 1`
+		
+		echo -n "."
+		
+		# wait some time
+		/bin/sleep 1
+	done
+	
+	echo " done"
+}
diff --git a/net/ibrdtnd/files/ibrdtn.uci b/net/ibrdtnd/files/ibrdtn.uci
new file mode 100644
index 000000000..ab4504487
--- /dev/null
+++ b/net/ibrdtnd/files/ibrdtn.uci
@@ -0,0 +1,175 @@
+#####################################
+# IBR-DTN daemon                    #
+#####################################
+
+config 'daemon' 'main'
+	# The local eid of the dtn node. Default is the hostname.
+#	option uri			dtn://node.dtn
+	
+	# logfile for standard output
+	option logfile		/tmp/ibrdtn.log
+	option errfile		/tmp/ibrdtn.err
+	
+	# debug level
+#	option debug		20
+
+	# block size limit
+#	option blocksize		512M
+#	option foreign_blocksize	128M
+
+
+#
+# If something bad happened, the safe mode will be activated.
+# These are the restrictions for safe mode only.
+#
+config 'daemon' 'safemode'
+	option forwarding	no
+	option storage		64M
+	option maxblock		16M
+#	option wait_mount	/dev/sda1
+
+
+#####################################
+# storage configuration             #
+#####################################
+
+config 'daemon' 'storage'
+	# possible engines are: simple, sqlite
+	option engine		simple
+	option blobs		/tmp/ibrdtn/blobs
+	option bundles		/tmp/ibrdtn/bundles
+#	option container	/tmp/ibrdtn/container.img
+#	option path			/tmp/ibrdtn/container
+#	option limit		1G
+
+
+#####################################
+# routing configuration             #
+#####################################
+
+#
+# In the "default" the daemon only delivers bundles to neighbors and static
+# available nodes. The alternative module "epidemic" spread all bundles to
+# all available neighbors.
+#
+config 'daemon' 'main'
+	# values: none | default | epidemic | flooding | prophet
+	option	routing		prophet
+#	option	forwarding	no
+#	option	fragmentation	yes
+
+#
+# static routing rules
+# - a rule is a regex pattern
+# - format is <target-scheme> <routing-node>
+#
+#config 'static-route'
+#	list pattern		^dtn://[[:alpha:]].moon.dtn/[[:alpha:]]
+#	option destination	dtn://router.dtn
+
+
+#####################################
+# static connections
+#####################################
+
+#config 'static-connection'
+#	option uri			dtn://node-five.dtn
+#	option address		10.0.0.5
+#	option port			4556
+#	option protocol		tcp
+#	option immediately	yes
+
+#config 'static-connection'
+#	option uri			dtn://node-ten
+#	option address		10.0.0.10
+#	option port			4556
+#	option protocol		udp
+#	option immediately	no
+
+
+#####################################
+# convergence layer configuration   #
+#####################################
+
+#
+# You can specify an multicast address to listen to for discovery announcements.
+# If no address is specified the multicast equivalent of broadcast is used.
+#
+config 'daemon' 'discovery'
+#	option address		224.0.0.1
+#	option timeout		5
+#	option crosslayer	yes
+
+config 'daemon' 'tcptuning'
+#	option 'idle_timeout'	120
+#	option 'nodelay'		yes
+#	option 'chunksize'		4096
+
+config 'network'
+	option type			tcp
+	option interface	eth0
+	option port			4556
+	
+#config 'network'
+#	option type			tcp
+#	option interface	wlan0
+#	option port			4556
+
+
+#####################################
+# bundle security protocol          #
+#####################################
+
+#
+# the level specifies the security constains
+#
+# 0 = no constrains (default)
+# 1 = accept only BAB authenticated bundles
+# 2 = accept only encrypted bundles
+# 3 = accept only BAB authenticated and encrypted bundles
+#
+
+#config 'daemon' 'security'
+#	option level		0
+#	option bab_key		/path/to/default-bab-key.mac
+#	option key_path		/path/to/security-keys
+#	option generate_dh	yes
+	
+#config 'daemon' 'tls'
+#	option certificate	/path/to/tls-cert.crt
+#	option key			/path/to/tls-key.key
+#	option trustedpath	/path/to/tls-ca
+#	option required		no
+#	option noencryption no
+
+
+#####################################
+# time synchronization              #
+#####################################
+
+#config 'daemon' 'timesync'
+#	option reference		yes
+#	option synchronize		yes
+#	option discovery_announcement	yes
+#	option sigma			1.001
+#	option psi			0.9
+#	option sync_level		0.1
+
+#####################################
+# DHT                               #
+#####################################
+
+config 'daemon' 'dht'
+#	option 'enabled'	'yes'
+#	option 'id'		'<enter your unique id here>'
+	option 'bootstrap'	'yes'
+#	option 'nodesfile'	'/tmp/dht_nodes.dat'
+	option 'port' 		'9999'
+	option 'enable_ipv6'	'no'
+#	option 'enable_ipv4'	'no'
+#	option 'bind_ipv4'	'127.0.0.1'
+#	option 'bind_ipv6'	'::1'
+	option 'ignore_neighbour_informations'		'yes'
+	option 'allow_neighbours_to_announce_me'	'no'
+	option 'allow_neighbour_announcement'		'no'
+
diff --git a/net/ibrdtnd/files/mkcontainer.sh b/net/ibrdtnd/files/mkcontainer.sh
new file mode 100644
index 000000000..5718111b3
--- /dev/null
+++ b/net/ibrdtnd/files/mkcontainer.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+#
+# This script creates a bundle storage of a given size.
+#
+# $1 = container file
+# $2 = size of the container in MB
+#
+
+help_message() {
+	echo "usage: "
+	echo " $0 <container file> <size in MB>"
+}
+
+if [ $# -le 1 ]; then
+	help_message
+	exit 1
+fi
+
+CONTAINER=$(cd "$(dirname "$1")"; pwd)/$(basename $1)
+SIZE=$2
+
+# check if the container already exists
+if [ -f $CONTAINER ]; then
+	echo "Aborted! The specified container already exists."
+	exit 1
+fi
+
+# create the container
+echo -n "creating the container file..."
+/bin/dd if=/dev/zero of=$CONTAINER bs=1M count=$SIZE >/dev/null 2>/dev/null
+echo " done" 
+
+# create file system
+echo -n "initializing ext3 filesystem for the container..."
+/usr/sbin/mkfs.ext3 -q -F $CONTAINER > /dev/null
+echo " done"
+
+# final hint
+echo "The container is now ready. To use it with IBR-DTN set the container with:"
+echo "# uci set ibrdtn.storage.container=$CONTAINER"
+echo "# uci set ibrdtn.storage.container_size=$SIZE"
+
+exit 0
diff --git a/net/ibrdtnd/files/mountcontainer.sh b/net/ibrdtnd/files/mountcontainer.sh
new file mode 100644
index 000000000..2eaed2f9b
--- /dev/null
+++ b/net/ibrdtnd/files/mountcontainer.sh
@@ -0,0 +1,122 @@
+#!/bin/sh
+#
+
+CONTAINER=`/sbin/uci -q get ibrdtn.storage.container`
+CPATH=`/sbin/uci -q get ibrdtn.storage.path`
+
+check_var() {
+	if [ -z "$1" ]; then
+		echo "$2"
+		exit 1
+	fi
+}
+
+check_path() {
+	if [ ! -d "$1" ]; then
+		echo "$2"
+		return 1
+	fi
+}
+
+check_file() {
+	if [ ! -f "$1" ]; then
+		echo "$2"
+		exit 1
+	fi
+}
+
+container_mount() {
+	CONTAINER=`/sbin/uci -q get ibrdtn.storage.container`
+	CPATH=`/sbin/uci -q get ibrdtn.storage.path`
+
+	if [ -z "`mount | grep ' on $CPATH '`" ]; then
+		# try to mount the container
+		/bin/mount -o loop $CONTAINER $CPATH
+
+		return $?
+	fi
+
+	return 0
+}
+
+container_reinitialize() {
+	SIZE=`/sbin/uci get -q ibrdtn.storage.container_size`
+	CONTAINER=`/sbin/uci -q get ibrdtn.storage.container`
+
+	# try to rebuild the container
+	if [ -n "$SIZE" ]; then
+		/bin/rm -f $CONTAINER
+		/usr/share/ibrdtn/mkcontainer.sh $CONTAINER $SIZE
+
+		if [ $? -eq 0 ]; then
+			container_mount
+			return $?
+		fi
+
+		return 1
+	fi
+
+	return 1
+}
+
+check_var $CONTAINER "Storage container not set in uci.\nuse: uci set ibrdtn.storage.container=<container-file>"
+check_var $CPATH "Storage container mount path not set in uci.\nuse: uci set ibrdtn.storage.path=<mount-path>"
+
+check_path $CPATH "Storage container mount path does not exist."
+if [ $? -gt 0 ]; then
+	/bin/mkdir -p $CPATH
+
+	if [ $? -gt 0 ]; then
+		echo "can not create container mount path."
+		exit 1
+	fi
+fi
+
+if [ "$1" == "-u" ]; then
+	/bin/umount $CPATH
+	exit 0
+fi
+
+if [ -n "`/bin/mount | grep $CPATH`" ]; then
+	echo "Container already mounted"
+	exit 0
+fi
+
+if [ ! -f "$CONTAINER" ]; then
+	echo "Storage container file $CONTAINER does not exist."
+	container_reinitialize
+	exit $?
+fi
+
+# try to mount the container
+container_mount
+
+if [ $? -gt 0 ]; then
+	echo -n "can not mount container file. checking... "
+	/usr/sbin/e2fsck -p $CONTAINER
+
+	if [ $? -gt 0 ]; then
+		echo " error"
+		echo "Container file $CONTAINER broken. Try to reinitialize the container."
+		container_reinitialize
+
+		if [ $? -eq 0 ]; then
+			echo "container ready!"
+			exit 0
+		else
+			exit 1
+		fi
+	fi
+	echo "done"
+
+	container_mount
+
+	if [ $? -gt 0 ]; then
+		echo "mount failed!"
+		exit 1
+	fi
+fi
+
+echo "container ready!"
+exit 0
+
diff --git a/net/ibrdtnd/files/safety-wrapper.sh b/net/ibrdtnd/files/safety-wrapper.sh
new file mode 100644
index 000000000..2f35283d3
--- /dev/null
+++ b/net/ibrdtnd/files/safety-wrapper.sh
@@ -0,0 +1,172 @@
+#!/bin/sh
+#
+# safety wrapper for IBR-DTN daemon
+#
+# Tasks:
+#  * start IBR-DTN daemon
+#  * restart the daemon after a crash
+#  * if respawning to fast, then slow down with backoff
+#  * check for enough space on disk and delete bundles if necessary.
+#  * clean the blob directory on startup
+#
+
+DTND=/usr/sbin/dtnd
+TMPCONF=/tmp/ibrdtn.config
+UCI=/sbin/uci
+
+getstate() {
+	$UCI -P/var/state -q get ibrdtn.$1
+	return $?
+}
+
+setstate() {
+	$UCI -P/var/state -q set ibrdtn.$1=$2
+	return $?
+}
+
+getconfig() {
+	$UCI -q get ibrdtn.$1
+	return $?
+}
+
+setconfig() {
+	$UCI -q set ibrdtn.$1=$2
+	return $?
+}
+
+# remove the old state file
+/bin/rm /var/state/ibrdtn
+
+# read uci configuration
+BLOB_PATH=`getconfig storage.blobs`
+BUNDLE_PATH=`getconfig storage.bundles`
+CONTAINER_PATH=`getconfig storage.path`
+CONTAINER_FILE=`getconfig storage.container`
+LOG_FILE=`getconfig main.logfile`
+ERR_FILE=`getconfig main.errfile`
+DEBUG_LEVEL=`getconfig main.debug`
+SAFEMODE=no
+
+# run a system check
+/bin/sh /usr/share/ibrdtn/systemcheck.sh
+
+if [ $? -eq 0 ]; then
+	# mount container if specified
+	if [ -n "$CONTAINER_FILE" ] && [ -n "$CONTAINER_PATH" ]; then
+		/bin/sh /usr/share/ibrdtn/mountcontainer.sh
+
+		# if the mount of the container failed
+		# switch to safe mode!
+		if [ $? -gt 0 ]; then
+			SAFEMODE=yes
+		fi
+	fi
+else
+	SAFEMODE=yes
+fi
+
+# create blob & bundle path
+if [ -n "$BLOB_PATH" ]; then
+	/bin/mkdir -p $BLOB_PATH
+
+	# clean the blob directory on startup
+	/bin/rm -f $BLOB_PATH/file*
+fi
+
+if [ -n "$BUNDLE_PATH" ]; then
+	/bin/mkdir -p $BUNDLE_PATH
+fi
+
+LOGGING=""
+if [ -n "$LOG_FILE" ]; then
+	LOGGING="$LOGGING > $LOG_FILE"
+else
+	LOGGING="$LOGGING > /dev/null"
+fi
+
+if [ -n "$ERR_FILE" ]; then
+	LOGGING="$LOGGING 2> $ERR_FILE"
+else
+	LOGGING="$LOGGING 2> /dev/null"
+fi
+
+if [ -z "$LOG_FILE" ] && [ -z "$ERR_FILE" ]; then
+	LOGGING="-q"
+fi
+
+# check for debugging option
+if [ -n "$DEBUG_LEVEL" ]; then
+	DEBUG_ARGS="-v -d ${DEBUG_LEVEL}"
+else
+	DEBUG_ARGS=""
+fi
+
+# create configuration
+if [ "$SAFEMODE" == "yes" ]; then
+	/bin/sh /usr/share/ibrdtn/build-config.sh --safe-mode $TMPCONF
+else
+	/bin/sh /usr/share/ibrdtn/build-config.sh $TMPCONF
+fi
+
+# set the crash counter to zero
+CRASH=0
+
+# run the daemon
+setstate state running
+
+while [ "`getstate state`" == "running" ]; do
+	# run a system check
+	/bin/sh /usr/share/ibrdtn/systemcheck.sh
+
+	# run in safe mode if the system check has failed
+	if [ $? -gt 0 ] && [ "$SAFEMODE" == "no" ]; then
+		SAFEMODE=yes
+		/usr/bin/logger -t "ibrdtn-safe-wrapper" -p 2 "system check failed! Switch to safe-mode settings."
+		/bin/sh /usr/share/ibrdtn/build-config.sh --safe-mode $TMPCONF
+	fi
+
+	# measure the running time
+	TIMESTART=`/bin/date +%s`
+	
+	# run the daemon
+	echo "${DTND} ${DEBUG_ARGS} -c ${TMPCONF} ${LOGGING}" | /bin/sh
+	
+	# measure the stopping time
+	TIMESTOP=`/bin/date +%s`
+	
+	# calc the running time
+	let TIMERUN=$TIMESTOP-$TIMESTART
+	
+	# reset the CRASH counter if there is one hour between the crashes
+	if [ $TIMERUN -ge 3600 ]; then
+		CRASH=0
+	fi
+	
+	# check if the daemon is crashed
+	if [ "`getstate state`" == "running" ]; then
+		# if the crash counter is higher than 20 switch to safe-mode settings
+		if [ $CRASH -eq 20 ] && [ "$SAFEMODE" == "no" ]; then
+			SAFEMODE=yes
+			/usr/bin/logger -t "ibrdtn-safe-wrapper" -p 2 "IBR-DTN daemon crashed 20 times! Switch to safe-mode settings."
+			/bin/sh /usr/share/ibrdtn/build-config.sh --safe-mode $TMPCONF
+		fi
+
+		# increment the crash counter
+		let CRASH=$CRASH+1
+		
+		# backoff wait timer
+		let WAIT=2**$CRASH
+		
+		# set a upper limit for the wait time
+		if [ $WAIT -ge 1800 ]; then
+			WAIT=1800
+		fi
+
+		# log the crash
+		/usr/bin/logger -t "ibrdtn-safe-wrapper" -p 2 "IBR-DTN daemon crashed $CRASH times! Wait $WAIT seconds."
+		
+		# wait sometime
+		/bin/sleep $WAIT
+	fi
+done
+
diff --git a/net/ibrdtnd/files/systemcheck.sh b/net/ibrdtnd/files/systemcheck.sh
new file mode 100644
index 000000000..3110bcf06
--- /dev/null
+++ b/net/ibrdtnd/files/systemcheck.sh
@@ -0,0 +1,101 @@
+#!/bin/sh
+#
+#
+
+check_mounted() {
+	DIR=$1
+	while [ "$DIR" != "/" ]; do
+		if [ -n "`mount | grep "$DIR"`" ]; then
+			return 0
+		fi
+
+		DIR=`dirname $DIR`
+	done
+	return 1
+}
+
+check_writable() {
+	CHECKFILE="$1/.container-lock"
+	/bin/touch $CHECKFILE
+
+	if [ $? -gt 0 ]; then
+		return 1;
+	fi
+
+	/bin/echo "0123456789" >> $CHECKFILE
+
+	if [ $? -gt 0 ]; then
+		return 2;
+	fi
+
+	/bin/rm $CHECKFILE
+
+	if [ $? -gt 0 ]; then
+		return 3;
+	fi
+}
+
+check_mountdev() {
+	# get wait_mount option
+	WAIT_MOUNT_DEV=`uci -q get ibrdtn.safemode.wait_mount`
+	
+	if [ $? -ne 0 ]; then
+		return 0
+	fi
+	
+	DATA=`mount | grep ${WAIT_MOUNT_DEV}`
+
+	if [ -n "${DATA}" ]; then
+		return 0
+	fi
+	
+	return 1
+}
+
+# check the storage device
+check_mountdev
+RET=$?
+
+if [ ${RET} -ne 0 ]; then
+	WAIT_SECONDS=60
+	/usr/bin/logger -t "systemcheck.sh" -p 2 "disk storage not ready, wait max. ${WAIT_SECONDS} seconds until it is mounted"
+	while [ ${RET} -ne 0 ] && [ ${WAIT_SECONDS} -ne 0 ]; do
+		sleep 1
+		let WAIT_SECONDS=WAIT_SECONDS-1
+		check_mountdev
+		RET=$?
+	done
+fi
+
+if [ ${RET} -ne 0 ]; then
+	# failed, storage not mounted
+	exit 1
+fi
+
+# get the path for the container
+CONTAINER=`uci -q get ibrdtn.storage.container`
+
+if [ -z "$CONTAINER" ]; then
+	exit 0
+fi
+
+CONTAINER_PATH=`dirname $CONTAINER`
+
+if [ -n "$CONTAINER_PATH" ]; then
+	# check if the container is on a mounted device
+	check_mounted $CONTAINER_PATH
+
+	if [ $? -gt 0 ]; then
+		# failed
+		exit 1
+	fi
+
+	# check if the device is writable
+	check_writable $CONTAINER_PATH
+
+	if [ $? -gt 0 ]; then
+		# failed
+		exit 1
+	fi
+fi
+