diff --git a/README.md b/README.md
index 84b9b1b..661434f 100644
--- a/README.md
+++ b/README.md
@@ -1,44 +1,25 @@
+
 # nsntrace
 > Perform network trace of a single process by using network namespaces.
 
-This application uses Linux network namespaces to perform network traces of a single application. The traces are saved as pcap files. And can later be analyzed by for instance Wireshark.
+This application uses Linux network namespaces to perform a network trace of a single application. The trace is saved as a pcap file. And can later be analyzed by for instance Wireshark or tshark.
 
 The nsntrace application is heavily inspired by the askbubuntu reply [here](https://askubuntu.com/a/499850).
 And uses the same approach only confined to a single C program.
 
-What the application does is use the clone syscall to create a new
-network namespace (CLONE_NEWNET) and from that namespace launch the
-requested process as well as start a trace using libpcap. This will ensure that all
-the packets we trace come from the process.
+What the application does is use the clone syscall to create a new network namespace (CLONE_NEWNET) and from that namespace launch the requested process as well as start a trace using libpcap. This will ensure that all the packets we trace come from the process.
 
-The problem we are left with is that the process is isolated in the
-namespace and cannot reach any other network. We get around that by
-creating virtual network interfaces. We keep one of them in the
-root network namespace and but the other one in the newly created one where
-our tracing takes place. We set the root namespaced one as the default gw
-of the trace namespaced virtual device.
+The problem we are left with is that the process is isolated in the namespace and cannot reach any other network. We get around that by creating virtual network interfaces. We keep one of them in the root network namespace and but the other one in the newly created one where our tracing takes place. We set the root namespaced one as the default gateway of the trace namespaced virtual device.
 
-And then to make sure we can reach our indented net, we use ip
-tables and NAT to forward all traffic from the virtual device to our
-default network interface.
+And then to make sure we can reach our intended net, we use iptables and NAT to forward all traffic from the virtual device to our default network interface.
 
-This will allow us to capture the packets from a single process while
-it is communicating with our default network. A limitation is that our
-ip address will be the NAT one of the virtual device.
+This will allow us to capture the packets from a single process while it is communicating with our default network. A limitation is that our ip address will be the NAT one of the virtual device.
 
-Another limitation is, that since we are using iptables and since
-we are tracing raw sockets. This application needs to be run as root.
+Another limitation is, that since we are using iptables and since we are tracing raw sockets. This application needs to be run as root.
 
-On many systems today the nameserver functionality is handled by an
-application such as systemd-resolved or dnsmasq and the nameserver
-address is a loopback address (like 127.0.0.53) where that application
-listens for incoming DNS queries.
+On many systems today the nameserver functionality is handled by an application such as systemd-resolved or dnsmasq and the nameserver address is a loopback address (like 127.0.0.53) where that application listens for incoming DNS queries.
 
-This will not work for us in this network namespace environment, since
-we have our own namespaced loopback device. To work around this one can use the
-`--use-public-dns` option to override resolv.conf in the namespace. Then nsntrace
-will use nameservers from Quad9 (9.9.9.9), Cloudflare (1.1.1.1), Google (8.8.8.8) and
-OpenDNS (208.67.222.222) to perform DNS queries.
+This will not work for us in this network namespace environment, since we have our own namespaced loopback device. To work around this one can use the `--use-public-dns` option to override resolv.conf in the namespace. Then nsntrace will use nameservers from Quad9 (9.9.9.9), Cloudflare (1.1.1.1), Google (8.8.8.8) and OpenDNS (208.67.222.222) to perform DNS queries.
 
 ## usage
     $ nsntrace
@@ -98,3 +79,27 @@ $ sudo nsntrace -f tcp -o - wget www.google.com  2> /dev/null | tshark -r -
 13   0.113167 142.250.74.36 → 172.16.42.255 TCP 66 80 → 51088 [FIN, ACK] Seq=13815 Ack=143 Win=66816 Len=0 TSval=2846449554 TSecr=1362504583
 14   0.113190 172.16.42.255 → 142.250.74.36 TCP 66 51088 → 80 [ACK] Seq=143 Ack=13816 Win=64128 Len=0 TSval=1362504595 TSecr=2846449554
 ```
+
+# building from source
+To build nsntrace from source the following steps are needed:
+
+```
+$ ./autogen.sh
+$ ./configure
+$ make
+```
+And to install:
+```
+$ sudo make install
+```
+
+## dependencies
+The packages needed to build nsntrace are (Debian/Ubuntu style naming):
+* automake
+* docbook-xml
+* docbook-xsl
+* iptables
+* libnl-route-3-dev
+* lippcap-dev
+* pkg-config
+* xsltproc
diff --git a/debian/changelog b/debian/changelog
index 94ef256..28e4862 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+nsntrace (4.5.g4d02e74-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Wed, 11 May 2022 02:38:41 -0000
+
 nsntrace (4-1) unstable; urgency=medium
 
   * New upstream version 4
diff --git a/src/net.c b/src/net.c
index c7063a8..4ae04ac 100644
--- a/src/net.c
+++ b/src/net.c
@@ -55,15 +55,10 @@
  * to interface with the Netlink API and perform network configuration.
  */
 
-#define IP_BASE "172.16.42"
-#define NS_IP IP_BASE ".255"
-#define GW_IP IP_BASE ".254"
-#define NS_IP_RANGE NS_IP "/31"
-#define GW_IP_RANGE GW_IP "/31"
+#define NS_IF_BASE "nscap"
+#define GW_IF_BASE "nsgw"
+
 
-#define IF_BASE "nsntrace"
-#define NS_IF IF_BASE "-netns"
-#define GW_IF IF_BASE
 
 static struct nl_sock *
 _nsntrace_net_get_nl_socket() {
@@ -293,19 +288,15 @@ static void
 _nsntrace_net_create_resolv_conf()
 {
 	int fd;
+	char resolv_path[PATH_MAX] = { 0, };
 	const char *resolv = "nameserver 9.9.9.9\n"         /* Quad9 */
 			     "nameserver 1.1.1.1\n"         /* Cloudflare */
 			     "nameserver 8.8.8.8\n"         /* Google */
 			     "nameserver 208.67.222.222\n"; /* OpenDNS */
 
-	if (mkdir(NSNTRACE_RUN_DIR, 0644) < 0) {
-		if (errno != EEXIST) {
-			perror("mkdir");
-			return;
-		}
-	}
 
-	char resolv_path[] = NSNTRACE_RUN_DIR "/resolv.confXXXXXX";
+	snprintf(resolv_path, PATH_MAX, "%s/%d/resolv.confXXXXXX",
+		 NSNTRACE_RUN_DIR, getppid());
 	if ((fd = mkstemp(resolv_path)) < 0) {
 		perror("mkstemp");
 		return;
@@ -393,6 +384,81 @@ _nsntrace_net_check_dns()
 		"Quad9, Cloudflare, Google and OpenDNS\n\n");
 }
 
+/*
+ * Attempt to find a free ip base (172.19.x) to use. We use randomization
+ * and check addresses that are already bound to our devices, this is to
+ * enable us to run multiple instances of nsntrace.
+ */
+static const char *
+_nsntrace_net_get_ip_base()
+{
+	char buf[1024];
+	char ip[16];
+	struct ifconf ifc;
+	struct timeval tval;
+	int s;
+	int i;
+
+	s = socket(AF_INET, SOCK_DGRAM, 0);
+	if(s < 0) {
+		perror("socket");
+		return NULL;
+	}
+
+	gettimeofday(&tval, NULL);
+	srand(tval.tv_usec);
+	while (1) {
+		int digit = rand() % 255;
+		snprintf(ip, 16, "172.19.%d", digit);
+
+		/* query available interfaces. */
+		ifc.ifc_len = sizeof(buf);
+		ifc.ifc_buf = buf;
+		if(ioctl(s, SIOCGIFCONF, &ifc) < 0)
+		{
+			perror("ioctl");
+			return NULL;
+		}
+
+		/* iterate through the list of interfaces. */
+		int found = 0;
+		for(i = 0; i < (ifc.ifc_len / sizeof(struct ifreq)); i++)
+		{
+			struct ifreq *item = &ifc.ifc_req[i];
+			char *addr = inet_ntoa(((struct sockaddr_in *)&item->ifr_addr)->sin_addr);
+
+			if (!strncmp(addr, ip, strlen(ip))) {
+				found = 1;
+				break;
+			}
+		}
+		if (found == 0) {
+			return strdup(ip);
+		}
+	}
+	return NULL;
+}
+
+int
+nsntrace_net_get_if_info(pid_t pid,
+			 struct nsntrace_if_info *info)
+{
+	const char *ip_base = _nsntrace_net_get_ip_base();
+	if (!ip_base) {
+		fprintf(stderr, "failed to allocate IP address");
+		return -1;
+	}
+
+	snprintf(info->ns_if, IFNAMSIZ, "%s%d", NS_IF_BASE, pid);
+	snprintf(info->gw_if, IFNAMSIZ, "%s%d", GW_IF_BASE, pid);
+	snprintf(info->ns_ip, IP_ADDR_LEN, "%s.255", ip_base);
+	snprintf(info->gw_ip, IP_ADDR_LEN, "%s.254", ip_base);
+	snprintf(info->ns_ip_range, IP_ADDR_LEN + 3, "%s/31", info->ns_ip);
+	snprintf(info->gw_ip_range, IP_ADDR_LEN + 3, "%s/31", info->gw_ip);
+
+	return 0;
+}
+
 /*
  * Set up the environment needed from the root network namespace point
  * of view. Create virtual ethernet interface (see above) and set our side
@@ -402,19 +468,20 @@ _nsntrace_net_check_dns()
  */
 int
 nsntrace_net_init(pid_t ns_pid,
-		  const char *device)
+		  const char *device,
+		  struct nsntrace_if_info *info)
 {
 	int ret = 0;
 
-	if ((ret = _nsntrace_net_create_veth(GW_IF, NS_IF, ns_pid)) < 0) {
+	if ((ret = _nsntrace_net_create_veth(info->gw_if, info->ns_if, ns_pid)) < 0) {
 		return ret;
 	}
 
-	if ((ret = _nsntrace_net_iface_up(GW_IF, GW_IP_RANGE, NULL)) < 0) {
+	if ((ret = _nsntrace_net_iface_up(info->gw_if, info->gw_ip_range, NULL)) < 0) {
 		return ret;
 	}
 
-	if ((ret = _nsntrace_net_set_nat(GW_IP_RANGE, GW_IF, device, 1)) < 0) {
+	if ((ret = _nsntrace_net_set_nat(info->gw_ip_range, info->gw_if, device, 1)) < 0) {
 		return ret;
 	}
 
@@ -426,19 +493,21 @@ nsntrace_net_init(pid_t ns_pid,
  * Teardown the temporary network trickery we created in init.
  */
 int
-nsntrace_net_deinit(const char *device)
+nsntrace_net_deinit(pid_t ns_pid,
+		    const char *device,
+		    struct nsntrace_if_info *info)
 {
 	int ret = 0;
 
-	if ((ret = _nsntrace_net_set_nat(GW_IP_RANGE, GW_IF, device, 0)) < 0) {
+	if ((ret = _nsntrace_net_set_nat(info->gw_ip_range, info->gw_if, device, 0)) < 0) {
 		return ret;
 	}
 
-	if ((ret = _nsntrace_net_iface_delete(NS_IF)) < 0) {
+	if ((ret = _nsntrace_net_iface_delete(info->ns_if)) < 0) {
 		return ret;
 	}
 
-	if ((ret = _nsntrace_net_iface_delete(GW_IF)) < 0) {
+	if ((ret = _nsntrace_net_iface_delete(info->gw_if)) < 0) {
 		return ret;
 	}
 
@@ -449,11 +518,12 @@ nsntrace_net_deinit(const char *device)
  * Set up the namespaced net infrastructure needed.
  */
 int
-nsntrace_net_ns_init(int use_public_dns)
+nsntrace_net_ns_init(int use_public_dns,
+		     struct nsntrace_if_info *info)
 {
 	int ret = 0;
 
-	if ((ret = _nsntrace_net_iface_up(NS_IF, NS_IP_RANGE, GW_IP)) < 0) {
+	if ((ret = _nsntrace_net_iface_up(info->ns_if, info->ns_ip_range, info->gw_ip)) < 0) {
 		return EXIT_FAILURE;
 	}
 
@@ -491,15 +561,3 @@ nsntrace_net_ip_forward_enabled()
 
 	return ch == '1';
 }
-
-const char *
-nsntrace_net_get_capture_interface()
-{
-	return NS_IF;
-}
-
-const char *
-nsntrace_net_get_capture_ip()
-{
-	return NS_IP;
-}
diff --git a/src/net.h b/src/net.h
index e63d173..ad8cf65 100644
--- a/src/net.h
+++ b/src/net.h
@@ -16,19 +16,34 @@
 #ifndef _NSNTRACE_NET_H_
 #define _NSNTRACE_NET_H
 
+#include <linux/if.h>
+
+#define IP_ADDR_LEN 16 // 4 sets of 3 numbers each separater by a dot + '\0'
 #define NSNTRACE_RUN_DIR "/run/nsntrace"
 
+struct nsntrace_if_info {
+    char ns_if[IFNAMSIZ];
+    char gw_if[IFNAMSIZ];
+    char ns_ip[16];
+    char gw_ip[16];
+    char ns_ip_range[19];
+    char gw_ip_range[19];
+};
+
 int nsntrace_net_init(pid_t ns_pid,
-                      const char *device);
+                      const char *device,
+                      struct nsntrace_if_info *info);
 
-int nsntrace_net_deinit(const char *device);
+int nsntrace_net_deinit(pid_t ns_pid,
+                        const char *device,
+                        struct nsntrace_if_info *info);
 
-int nsntrace_net_ns_init(int use_public_dns);
+int nsntrace_net_ns_init(int use_public_dns,
+                         struct nsntrace_if_info *info);
 
 int nsntrace_net_ip_forward_enabled();
 
-const char *nsntrace_net_get_capture_ip();
-
-const char *nsntrace_net_get_capture_interface();
+int nsntrace_net_get_if_info(pid_t pid,
+                             struct nsntrace_if_info *info);
 
 #endif
diff --git a/src/nsntrace.c b/src/nsntrace.c
index 270947d..e19cfec 100644
--- a/src/nsntrace.c
+++ b/src/nsntrace.c
@@ -82,6 +82,11 @@ struct nsntrace_options {
 	char * const *args;
 };
 
+struct nsntrace_common {
+	struct nsntrace_options *options;
+	struct nsntrace_if_info if_info;
+};
+
 #define PUBLIC_DNS 1000
 static const char *short_opt = "+o:d:u:f:h";
 static struct option long_opt[] = {
@@ -146,6 +151,15 @@ static int _nsntrace_unlink_cb(const char *fpath,
     return rv;
 }
 
+static void
+_nsntrace_remove_rundir(pid_t pid)
+{
+	char path[PATH_MAX] = { 0, };
+
+	snprintf(path, PATH_MAX, "%s/%d", NSNTRACE_RUN_DIR, getppid());
+	nftw(path, _nsntrace_unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
+}
+
 static void _nsntrace_remove_ns()
 {
 	char netns_path[PATH_MAX];
@@ -157,7 +171,7 @@ static void _nsntrace_remove_ns()
 	}
 
 	/* clean up run-time files */
-	nftw(NSNTRACE_RUN_DIR, _nsntrace_unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
+	_nsntrace_remove_rundir(getppid());
 }
 
 static void
@@ -226,12 +240,10 @@ out:
 }
 
 static void
-_nsntrace_start_tracer(struct nsntrace_options *options)
+_nsntrace_start_tracer(struct nsntrace_options *options,
+					   struct nsntrace_if_info *info)
 {
 	int ret;
-	const char *ip;
-	const char *interface;
-
 	/*
 	 * If outfile is a lone dash ("-"), the user wants us to output to STDOUT,
 	 * in that case we avoid printing anything else to STDOUT and use STDERR
@@ -250,14 +262,11 @@ _nsntrace_start_tracer(struct nsntrace_options *options)
 		}
 	}
 
-	ip = nsntrace_net_get_capture_ip();
-	interface = nsntrace_net_get_capture_interface();
-
 	fprintf(where, "Starting network trace of '%s' on interface %s.\n"
 		"Your IP address in this trace is %s.\n"
 		"Use ctrl-c to end at any time.\n\n",
-		options->args[0], options->device, ip);
-	ret = nsntrace_capture_start(interface, options->filter, fp);
+		options->args[0], options->device, info->ns_ip);
+	ret = nsntrace_capture_start(info->ns_if, options->filter, fp);
 	if (ret != 0) {
 		exit(ret);
 	}
@@ -344,15 +353,16 @@ static int
 netns_main(void *arg) {
 	int status;
 	int ret = EXIT_SUCCESS;
-	struct nsntrace_options *options = (struct nsntrace_options *) arg;
+	struct nsntrace_common *common = (struct nsntrace_common *) arg;
+	struct nsntrace_options *options = common->options;
 
-	if (nsntrace_net_ns_init(options->use_public_dns) < 0) {
+	if (nsntrace_net_ns_init(options->use_public_dns, &common->if_info) < 0) {
 		fprintf(stderr, "failed to setup network environment\n");
 		return EXIT_FAILURE;
 	}
 
 	_nsntrace_handle_signals(_nsntrace_cleanup_ns_signal_callback);
-	_nsntrace_start_tracer(options);
+	_nsntrace_start_tracer(common->options, &common->if_info);
 
 	_nsntrace_set_name();
 
@@ -384,7 +394,7 @@ netns_main(void *arg) {
 		_nsntrace_cleanup_ns();
 		exit(ret);
 	} else { /* child - tracee */
-		_nsntrace_start_tracee(options);
+		_nsntrace_start_tracee(common->options);
 	}
 
 	return ret;
@@ -463,11 +473,35 @@ _nsntrace_parse_options(struct nsntrace_options *options,
 	}
 }
 
+/*
+ * Create the pid based run dir for this nsntrace instance.
+ * This is for storing run-time files and to be able to cleanup
+ * easily without removing other nsntrace instances files.
+ */
+static void
+_nsntrace_mkrundir()
+{
+	char path[PATH_MAX] = { 0, };
+
+	if (mkdir(NSNTRACE_RUN_DIR, 0644) < 0) {
+		if (errno != EEXIST) {
+			perror("mkdir");
+		}
+	}
+	snprintf(path, PATH_MAX, "%s/%d", NSNTRACE_RUN_DIR, getpid());
+	if (mkdir(path, 0644) < 0) {
+		if (errno != EEXIST) {
+			perror("mkdir");
+		}
+	}
+}
+
 int
 main(int argc, char **argv)
 {
 	struct nsntrace_options options = { 0 };
-	pid_t pid;
+	struct nsntrace_common common = { &options,  };
+	pid_t pid = 0;
 	int status;
 	int ret = EXIT_SUCCESS;
 
@@ -490,18 +524,26 @@ main(int argc, char **argv)
 		exit(EXIT_FAILURE);
 	}
 
+	_nsntrace_mkrundir();
+
+	if (nsntrace_net_get_if_info(getpid(), &common.if_info) < 0) {
+		ret = EXIT_FAILURE;
+		goto out;
+	}
+
 	/* here we create a new process in a new network namespace */
 	pid = clone(netns_main, child_stack + STACK_SIZE,
-		    CLONE_NEWNET | SIGCHLD, &options);
+		    CLONE_NEWNET | SIGCHLD, &common);
 	if (pid < 0) {
-		fprintf(stderr, "clone failed\n");
-		exit(EXIT_FAILURE);
+		perror("clone");
+		ret = EXIT_FAILURE;
+		goto out;
 	}
 
 	_nsntrace_handle_signals(_nsntrace_cleanup);
 
-	if ((ret = nsntrace_net_init(pid, options.device)) < 0 ||
-			(ret = nsntrace_capture_check_device(options.device))) {
+	if ((ret = nsntrace_net_init(pid, options.device, &common.if_info)) < 0 ||
+	    (ret = nsntrace_capture_check_device(options.device))) {
 		fprintf(stderr, "Failed to setup networking environment\n");
 		kill(pid, SIGKILL);
 		goto out;
@@ -516,6 +558,9 @@ main(int argc, char **argv)
 	}
 
 out:
-	nsntrace_net_deinit(options.device);
+	if (pid != 0) {
+		nsntrace_net_deinit(pid, options.device, &common.if_info);
+	}
+	_nsntrace_remove_rundir(getpid());
 	return ret;
 }
diff --git a/tests/check_cleanup.sh b/tests/check_cleanup.sh
index 8b39cd9..d0053b7 100755
--- a/tests/check_cleanup.sh
+++ b/tests/check_cleanup.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 # HUP INT QUIT ABRT SEGV TERM
-signals='1 2 3 6 11 15'
+set -- 1 2 3 6 11 15
 timeout=1
 ip="172.16.42.254"
 if=nsntrace
@@ -10,37 +10,41 @@ check_cleanup() {
     # sleep to allow for cleanup after signal
     sleep 1
 
-    (sudo iptables -w -t nat -L | grep $ip) && {
+    (sudo iptables -w -t nat -L | grep "$ip") && {
         echo "Rules not cleaned up after signal $signal"
         exit 1
     }
 
-    (sudo ip link | grep $if) && {
+    (sudo ip link | grep "$if") && {
         echo "Link not cleaned up after signal $signal"
         exit 1
     }
 
-    ls /run/nsntrace > /dev/null 2>&1 && {
+    ls "/run/nsntrace/$1" > /dev/null 2>&1 && {
         echo "run-time files not cleaned up after signal $signal"
         exit 1
     }
 
-    rm -rf *.pcap
+    rm -f -- *.pcap
 }
 
 start_and_kill() {
-    local signal=$1
+    sig="$1"
 
     sudo ../src/nsntrace ./test_program_dummy.sh &
-    sleep $timeout
+    sleep "$timeout"
     pid=$(pidof nsntrace)
-    sudo kill -$signal $pid
+    sudo kill "-$sig" "$pid"
 
-    check_cleanup
+    check_cleanup "$pid"
+    unset sig
  }
 
-for signal in $signals; do
-    start_and_kill $signal
+for signal ; do
+    start_and_kill "$signal"
 done
 
+sudo ../src/nsntrace ./test_program_dummy_ends.sh
+check_cleanup "$!"
+
 exit 0
diff --git a/tests/check_multiple.sh b/tests/check_multiple.sh
new file mode 100755
index 0000000..6a444cc
--- /dev/null
+++ b/tests/check_multiple.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+num_packets=10
+
+launch_nsntrace()
+{
+    id="$1"
+    filter="icmp[icmptype]==icmp-echo"
+
+    sudo ../src/nsntrace  -f "$filter" --use-public-dns -o "$id.pcap" ping -c "$num_packets" google.com > /dev/null 2>&1 &
+    sleep 1.0e-3
+
+    unset id filter
+}
+
+for i in $(seq 5); do
+    launch_nsntrace "$i"
+done
+
+sleep 20
+
+for i in $(seq 5); do
+    captured=$(tshark -r "$i.pcap" | wc -l)
+    [ "$captured" = "$num_packets" ] || {
+        echo "failed to capture all packets"
+        exit 1
+    }
+done
+
+rm -f -- *.pcap
+exit 0
diff --git a/tests/check_namespaced.sh b/tests/check_namespaced.sh
index 8390970..2ce3758 100755
--- a/tests/check_namespaced.sh
+++ b/tests/check_namespaced.sh
@@ -1,17 +1,17 @@
 #!/bin/sh
 
 packets=99
-cmd="./udp_send 1337 $packets"
 filter="udp port 1337"
 
 # start sending packages non-namespaced
  ./udp_send 1337 -1 &
 
 # stop the non-namespaced udp_send on exit
-trap "kill $(pidof udp_send)" EXIT
+pidof_udp_send=$(pidof udp_send)
+trap 'kill "$pidof_udp_send"' EXIT
 
 # make sure we only capture the packets from the namespaced version
-sudo ../src/nsntrace -d lo -f "$filter" $cmd | grep "$packets packets" || {
+sudo ../src/nsntrace -d lo -f "$filter" ./udp_send 1337 "$packets" | grep "$packets packets" || {
     echo "Did not capture $packets packets!"
     exit 1
 }
diff --git a/tests/check_return_code.sh b/tests/check_return_code.sh
index 4d5bfb3..d88c828 100755
--- a/tests/check_return_code.sh
+++ b/tests/check_return_code.sh
@@ -27,6 +27,6 @@ check_return_code 1 -f "broken filter" /bin/true
 check_return_code 1 -o /path/does/not/exist /bin/true
 check_return_code 1 -d invalid_device /bin/true
 
-rm -rf *.pcap
+rm -f -- *.pcap
 
 exit ${RET}
diff --git a/tests/test_program_dummy.sh b/tests/test_program_dummy.sh
index a4daef5..1d6ded9 100755
--- a/tests/test_program_dummy.sh
+++ b/tests/test_program_dummy.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
 
-while [ 1 ]; do
+while true ; do
     sleep 1
 done
diff --git a/tests/test_program_dummy_ends.sh b/tests/test_program_dummy_ends.sh
new file mode 100755
index 0000000..3348112
--- /dev/null
+++ b/tests/test_program_dummy_ends.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+sleep 5
+
diff --git a/tests/udp_send.c b/tests/udp_send.c
index 8a0f506..a59c63a 100644
--- a/tests/udp_send.c
+++ b/tests/udp_send.c
@@ -11,15 +11,19 @@
 int main(int argc, char **argv)
 {
 	struct sockaddr_in addr = { 0 };
-	int port, num, s;
+	int port, num, s, interval = 0;
 
-	if (argc != 3) {
-		fprintf(stderr, "usage: udp_send port num_packets\n");
+	if (argc < 3) {
+		fprintf(stderr, "usage: udp_send port num_packets [interval]\n");
 		exit(EXIT_FAILURE);
 	}
 	port = atoi(argv[1]);
 	num = atoi(argv[2]);
 
+	if (argc > 3) {
+		interval = atoi(argv[3]);
+	}
+
 	if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
 		fprintf(stderr, "failed to create socket\n");
 		exit(EXIT_FAILURE);
@@ -39,6 +43,8 @@ int main(int argc, char **argv)
 			fprintf(stderr, "failed to send message\n");
 			exit(EXIT_FAILURE);
 		}
+
+		sleep(interval);
 	}
 
 	return 0;