29 #include <libdaemon/daemon.h>
58 #include <sys/ioctl.h>
59 #include <sys/socket.h>
61 #include <linux/if_tun.h>
67 char clonedev[] =
"/dev/net/tun";
77 if( (fd = open(clonedev, O_RDWR)) < 0 ) {
82 memset(&ifr, 0,
sizeof(ifr));
84 ifr.ifr_flags = flags;
90 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
94 if( (err = ioctl(fd, TUNSETIFF, (
void *) &ifr)) < 0 ) {
103 strcpy(dev, ifr.ifr_name);
123 float throughput_sum_up = 0;
124 float throughput_sum_down = 0;
126 for (
int i = 0; i < 5; ++i) {
131 std::cout <<
" up: " << setiosflags(ios::right) << setw(12) << setiosflags(ios::fixed) << setprecision(2) << (throughput_sum_up/1024) <<
" kB/s ";
132 std::cout <<
" down: " << setiosflags(ios::right) << setw(12) << setiosflags(ios::fixed) << setprecision(2) << (throughput_sum_down/1024) <<
" kB/s\r" << std::flush;
135 if (throughput_pos > 4) throughput_pos = 0;
145 : dtn::api::
Client(app, stream), _stream(stream), _fd(-1)
147 char tun_name[IFNAMSIZ];
149 strcpy(tun_name, ptp_dev.c_str());
152 tun_device = tun_name;
164 virtual ~TUN2BundleGateway()
181 void process(
const dtn::data::EID &endpoint,
unsigned int lifetime = 60) {
185 ssize_t ret = ::read(_fd, data,
sizeof(data));
211 const std::string& getDeviceName()
const
222 std::string tun_device;
234 stream->read(data,
sizeof(data));
235 size_t ret = stream->gcount();
237 if (::write(_fd, data, ret) < 0)
254 if (_gateway != NULL)
255 _gateway->shutdown();
261 std::cout <<
"-- dtntunnel (IBR-DTN) --" << std::endl;
262 std::cout <<
"Syntax: " << argv0 <<
" [options] <endpoint>" << std::endl;
263 std::cout <<
" -h Display help message" << std::endl;
264 std::cout <<
" -d <dev> Virtual network device to create (default: tun0)" << std::endl;
265 std::cout <<
" -s <name> Application suffix of the local endpoint (default: tunnel)" << std::endl;
266 std::cout <<
" -l <seconds> Lifetime of each packet (default: 60)" << std::endl;
267 std::cout <<
" -t Show throughput" << std::endl;
268 #ifdef HAVE_LIBDAEMON
269 std::cout <<
" -D Daemonize the process" << std::endl;
270 std::cout <<
" -k Stop the running daemon" << std::endl;
271 std::cout <<
" -p <file> Store the pid in this pidfile" << std::endl;
275 #ifdef HAVE_LIBDAEMON
276 static char* __daemon_pidfile__ = NULL;
278 static const char* __daemon_pid_file_proc__(
void) {
279 return __daemon_pidfile__;
283 int main(
int argc,
char *argv[])
288 std::string ptp_dev(
"tun0");
289 std::string app_name(
"tunnel");
290 std::string endpoint(
"dtn:none");
291 unsigned int lifetime = 60;
292 bool daemonize =
false;
293 bool stop_daemon =
false;
295 bool throughput =
false;
298 signal(SIGINT,
term);
299 signal(SIGTERM,
term);
300 signal(SIGQUIT,
term);
302 #ifdef HAVE_LIBDAEMON
303 while ((c = getopt (argc, argv,
"td:s:l:hDkp:")) != -1)
305 while ((c = getopt (argc, argv,
"td:s:l:h")) != -1)
309 #ifdef HAVE_LIBDAEMON
336 lifetime = atoi(optarg);
345 for (index = optind; index < argc; ++index)
350 endpoint = std::string(argv[index]);
358 if (!stop_daemon && (optindex < 1)) {
print_help(argv[0]); exit(0); }
362 const unsigned char logopts = 0;
373 #ifdef HAVE_LIBDAEMON
387 #ifdef HAVE_LIBDAEMON
390 #ifdef HAVE_DAEMON_RESET_SIGS
392 if (daemon_reset_sigs(-1) < 0) {
398 if (daemon_unblock_sigs(-1) < 0) {
406 daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);
409 if (pidfile.length() > 0) {
410 __daemon_pidfile__ =
new char[pidfile.length() + 1];
411 ::strcpy(__daemon_pidfile__, pidfile.c_str());
412 daemon_pid_file_proc = __daemon_pid_file_proc__;
423 if ((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0)
426 return ret < 0 ? 1 : 0;
430 if ((pid = daemon_pid_file_is_running()) >= 0) {
436 if (daemon_retval_init() < 0) {
442 if ((pid = daemon_fork()) < 0) {
445 daemon_retval_done();
452 if ((ret = daemon_retval_wait(20)) < 0) {
461 if (daemon_close_all(-1) < 0) {
465 daemon_retval_send(1);
468 daemon_retval_send(255);
469 daemon_signal_done();
470 daemon_pid_file_remove();
476 if (daemon_pid_file_create() < 0) {
478 daemon_retval_send(2);
481 daemon_retval_send(255);
482 daemon_signal_done();
483 daemon_pid_file_remove();
489 daemon_retval_send(0);
502 TUN2BundleGateway gateway(app_name, conn, ptp_dev);
517 if (!daemonize && throughput) {
521 sev.sigev_notify = SIGEV_SIGNAL;
522 sev.sigev_signo = SIGRTMIN;
523 sev.sigev_value.sival_ptr = &timerid;
526 timer_create(CLOCK_MONOTONIC, &sev, &timerid);
529 struct itimerspec its;
530 size_t freq_nanosecs = 200000000;
531 its.it_value.tv_sec = freq_nanosecs / 1000000000;;
532 its.it_value.tv_nsec = freq_nanosecs % 1000000000;
533 its.it_interval.tv_sec = its.it_value.tv_sec;
534 its.it_interval.tv_nsec = its.it_value.tv_nsec;
536 if (timer_settime(timerid, 0, &its, NULL) == -1) {
546 gateway.process(eid, lifetime);
557 #ifdef HAVE_LIBDAEMON
561 daemon_retval_send(255);
562 daemon_signal_done();
563 daemon_pid_file_remove();
567 std::cout << std::endl;