29 #include <libdaemon/daemon.h>
57 #include <sys/ioctl.h>
58 #include <sys/socket.h>
60 #include <linux/if_tun.h>
66 char clonedev[] =
"/dev/net/tun";
76 if( (fd = open(clonedev, O_RDWR)) < 0 ) {
81 memset(&ifr, 0,
sizeof(ifr));
83 ifr.ifr_flags = flags;
89 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
93 if( (err = ioctl(fd, TUNSETIFF, (
void *) &ifr)) < 0 ) {
102 strcpy(dev, ifr.ifr_name);
122 float throughput_sum_up = 0;
123 float throughput_sum_down = 0;
125 for (
int i = 0; i < 5; ++i) {
130 std::cout <<
" up: " << setiosflags(ios::right) << setw(12) << setiosflags(ios::fixed) << setprecision(2) << (throughput_sum_up/1024) <<
" kB/s ";
131 std::cout <<
" down: " << setiosflags(ios::right) << setw(12) << setiosflags(ios::fixed) << setprecision(2) << (throughput_sum_down/1024) <<
" kB/s\r" << std::flush;
134 if (throughput_pos > 4) throughput_pos = 0;
144 : dtn::api::
Client(app, stream), _stream(stream), _fd(-1)
146 char tun_name[IFNAMSIZ];
148 strcpy(tun_name, ptp_dev.c_str());
151 tun_device = tun_name;
163 virtual ~TUN2BundleGateway()
180 void process(
const dtn::data::EID &endpoint,
unsigned int lifetime = 60) {
184 ssize_t ret = ::read(_fd, data,
sizeof(data));
210 const std::string& getDeviceName()
const
221 std::string tun_device;
233 stream->read(data,
sizeof(data));
234 size_t ret = stream->gcount();
236 if (::write(_fd, data, ret) < 0)
253 if (_gateway != NULL)
254 _gateway->shutdown();
260 std::cout <<
"-- dtntunnel (IBR-DTN) --" << std::endl;
261 std::cout <<
"Syntax: " << argv0 <<
" [options] <endpoint>" << std::endl;
262 std::cout <<
" <endpoint> Destination of outgoing bundles" << std::endl << std::endl;
263 std::cout <<
"* optional parameters *" << std::endl;
264 std::cout <<
" -h Display help message" << std::endl;
265 std::cout <<
" -d <dev> Virtual network device to create (default: tun0)" << std::endl;
266 std::cout <<
" -s <name> Application suffix of the local endpoint (default: tunnel)" << std::endl;
267 std::cout <<
" -l <seconds> Lifetime of each packet (default: 60)" << std::endl;
268 std::cout <<
" -t Show throughput" << std::endl;
269 #ifdef HAVE_LIBDAEMON
270 std::cout <<
" -D Daemonize the process" << std::endl;
271 std::cout <<
" -k Stop the running daemon" << std::endl;
272 std::cout <<
" -p <file> Store the pid in this pidfile" << std::endl;
276 #ifdef HAVE_LIBDAEMON
277 static char* __daemon_pidfile__ = NULL;
279 static const char* __daemon_pid_file_proc__(
void) {
280 return __daemon_pidfile__;
284 int main(
int argc,
char *argv[])
289 std::string ptp_dev(
"tun0");
290 std::string app_name(
"tunnel");
291 std::string endpoint(
"dtn:none");
292 unsigned int lifetime = 60;
293 bool daemonize =
false;
294 bool stop_daemon =
false;
296 bool throughput =
false;
300 sighandler.
handle(SIGINT);
301 sighandler.
handle(SIGTERM);
302 sighandler.
handle(SIGQUIT);
304 #ifdef HAVE_LIBDAEMON
305 while ((c = getopt (argc, argv,
"td:s:l:hDkp:")) != -1)
307 while ((c = getopt (argc, argv,
"td:s:l:h")) != -1)
311 #ifdef HAVE_LIBDAEMON
338 lifetime = atoi(optarg);
347 for (index = optind; index < argc; ++index)
352 endpoint = std::string(argv[index]);
360 if (!stop_daemon && (optindex < 1)) {
print_help(argv[0]); exit(0); }
367 const unsigned char logopts = 0;
378 #ifdef HAVE_LIBDAEMON
392 #ifdef HAVE_LIBDAEMON
395 #ifdef HAVE_DAEMON_RESET_SIGS
397 if (daemon_reset_sigs(-1) < 0) {
403 if (daemon_unblock_sigs(-1) < 0) {
411 daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);
414 if (pidfile.length() > 0) {
415 __daemon_pidfile__ =
new char[pidfile.length() + 1];
416 ::strcpy(__daemon_pidfile__, pidfile.c_str());
417 daemon_pid_file_proc = __daemon_pid_file_proc__;
428 if ((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0)
431 return ret < 0 ? 1 : 0;
435 if ((pid = daemon_pid_file_is_running()) >= 0) {
441 if (daemon_retval_init() < 0) {
447 if ((pid = daemon_fork()) < 0) {
450 daemon_retval_done();
457 if ((ret = daemon_retval_wait(20)) < 0) {
466 if (daemon_close_all(-1) < 0) {
470 daemon_retval_send(1);
473 daemon_retval_send(255);
474 daemon_signal_done();
475 daemon_pid_file_remove();
481 if (daemon_pid_file_create() < 0) {
483 daemon_retval_send(2);
486 daemon_retval_send(255);
487 daemon_signal_done();
488 daemon_pid_file_remove();
494 daemon_retval_send(0);
507 TUN2BundleGateway gateway(app_name, conn, ptp_dev);
522 if (!daemonize && throughput) {
526 sev.sigev_notify = SIGEV_SIGNAL;
527 sev.sigev_signo = SIGRTMIN;
528 sev.sigev_value.sival_ptr = &timerid;
531 timer_create(CLOCK_MONOTONIC, &sev, &timerid);
534 struct itimerspec its;
535 size_t freq_nanosecs = 200000000;
536 its.it_value.tv_sec = freq_nanosecs / 1000000000;;
537 its.it_value.tv_nsec = freq_nanosecs % 1000000000;
538 its.it_interval.tv_sec = its.it_value.tv_sec;
539 its.it_interval.tv_nsec = its.it_value.tv_nsec;
541 if (timer_settime(timerid, 0, &its, NULL) == -1) {
551 gateway.process(eid, lifetime);
562 #ifdef HAVE_LIBDAEMON
566 daemon_retval_send(255);
567 daemon_signal_done();
568 daemon_pid_file_remove();
572 std::cout << std::endl;