Imported Upstream version 0.3.4
[anytun.git] / src / options.cpp
1 /*
2  *  anytun
3  *
4  *  The secure anycast tunneling protocol (satp) defines a protocol used
5  *  for communication between any combination of unicast and anycast
6  *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
7  *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
8  *  ethernet, ip, arp ...). satp directly includes cryptography and
9  *  message authentication based on the methodes used by SRTP.  It is
10  *  intended to deliver a generic, scaleable and secure solution for
11  *  tunneling and relaying of packets of any protocol.
12  *
13  *
14  *  Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl,
15  *                          Christian Pointner <satp@wirdorange.org>
16  *
17  *  This file is part of Anytun.
18  *
19  *  Anytun is free software: you can redistribute it and/or modify
20  *  it under the terms of the GNU General Public License as published by
21  *  the Free Software Foundation, either version 3 of the License, or
22  *  any later version.
23  *
24  *  Anytun is distributed in the hope that it will be useful,
25  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
26  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  *  GNU General Public License for more details.
28  *
29  *  You should have received a copy of the GNU General Public License
30  *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
31  */
32
33 #include <cstring>
34 #include <iostream>
35 #include <queue>
36 #include <string>
37 #include <sstream>
38
39 #include "datatypes.h"
40 #include "version.h"
41
42 #include "options.h"
43 #include "log.h"
44 #include "authAlgoFactory.h"
45
46 std::ostream& operator<<(std::ostream& stream, syntax_error const& error)
47 {
48   stream << "syntax error: " << error.what() << std::endl;
49   if(error.pos >= 0) {
50     stream << "              ";
51     for(int32_t i = 0; i < error.pos; ++i) { stream << " "; }
52     return stream << "^";
53   }
54   return stream;
55 }
56
57 std::ostream& operator<<(std::ostream& stream, role_t const& role)
58 {
59   switch(role) {
60   case ROLE_LEFT:
61     stream << "left";
62     break;
63   case ROLE_RIGHT:
64     stream << "right";
65     break;
66   default:
67     stream << "unknown";
68     break;
69   }
70   return stream;
71 }
72
73 void OptionHost::init(std::string addrPort)
74 {
75   std::string origAddrPort(addrPort);
76   size_t pos = addrPort.find_first_of("[");
77
78   if(pos != std::string::npos && pos != 0) {
79     throw syntax_error(origAddrPort, pos);  // an [ was found but not at the beginning;
80   }
81
82   bool hasPort = false;
83   if(pos != std::string::npos) {
84     addrPort.erase(pos, 1);
85     pos = addrPort.find_first_of("]");
86
87     if(pos == std::string::npos) {
88       throw syntax_error(origAddrPort, origAddrPort.length());  //no trailing ] although an leading [ was found
89     }
90
91     if(pos < addrPort.length()-2) {
92       if(addrPort[pos+1] != ':') {
93         throw syntax_error(origAddrPort, pos+2);  // wrong port delimieter
94       }
95
96       addrPort[pos+1] = '/';
97       hasPort = true;
98     } else if(pos != addrPort.length()-1) {
99       throw syntax_error(origAddrPort, pos+2);  // too few characters left
100     }
101
102     addrPort.erase(pos, 1);
103   } else {
104     pos = addrPort.find_first_of(":");
105     if(pos != std::string::npos && pos == addrPort.find_last_of(":")) {
106       // an ':' has been found and it is the only one -> assuming port present
107       hasPort = true;
108       addrPort[pos] = '/';
109     }
110   }
111
112   if(hasPort) {
113     std::stringstream tmp_stream(addrPort);
114
115     getline(tmp_stream, addr, '/');
116     if(!tmp_stream.good()) {
117       throw syntax_error(origAddrPort, addr.length());
118     }
119
120     tmp_stream >> port;
121   } else {
122     addr = addrPort;
123     port = "2323"; // default sync port
124   }
125 }
126
127 std::istream& operator>>(std::istream& stream, OptionHost& host)
128 {
129   std::string tmp;
130   stream >> tmp;
131   host.init(tmp);
132   return stream;
133 }
134
135 void OptionNetwork::init(std::string network)
136 {
137   std::stringstream tmp_stream(network);
138   getline(tmp_stream, net_addr, '/');
139   if(!tmp_stream.good()) {
140     throw syntax_error(network, net_addr.length());
141   }
142   tmp_stream >> prefix_length;
143 }
144
145 std::istream& operator>>(std::istream& stream, OptionNetwork& network)
146 {
147   std::string tmp;
148   stream >> tmp;
149   network.init(tmp);
150   return stream;
151 }
152
153 Options* Options::inst = NULL;
154 Mutex Options::instMutex;
155 Options& gOpt = Options::instance();
156
157 Options& Options::instance()
158 {
159   Lock lock(instMutex);
160   static instanceCleaner c;
161   if(!inst) {
162     inst = new Options();
163   }
164
165   return *inst;
166 }
167
168 Options::Options() : key_(uint32_t(0)), salt_(uint32_t(0))
169 {
170 #if defined(ANYCTR_OPTIONS)
171   progname_ = "anytun-controld";
172 #elif defined(ANYCONF_OPTIONS)
173   progname_ = "anytun-config";
174 #else
175   progname_ = "anytun";
176 #endif
177
178   cluster_opts = false;
179   connection_opts = false;
180
181   daemonize_ = true;
182   username_ = "";
183   groupname_ = "";
184   chroot_dir_ = "";
185   pid_file_ = "";
186
187   debug_ = false;
188
189   file_name_ = "";
190   bind_to_.addr = "127.0.0.1";
191   bind_to_.port = "2323";
192
193   resolv_addr_type_ = ANY;
194
195   local_.addr = "";
196   local_.port = "4444";
197   remote_.addr = "";
198   remote_.port = "4444";
199   local_sync_.addr = "";
200   local_sync_.port = "";
201
202   dev_name_ = "";
203   dev_type_ = "";
204   post_up_script_ = "";
205
206   sender_id_ = 0;
207   mux_ = 0;
208   seq_window_size_ = 0;
209
210 #if !defined(ANYCONF_OPTIONS)
211 #ifndef NO_CRYPT
212   cipher_ = "aes-ctr";
213   auth_algo_ = "sha1";
214   auth_tag_length_ = 10;
215   kd_prf_ = "aes-ctr";
216 #else
217   cipher_ = "null";
218   auth_algo_ = "null";
219   auth_tag_length_ = 0;
220   kd_prf_ = "null";
221 #endif
222 #else
223   cipher_ = "null";
224   auth_algo_ = "null";
225   auth_tag_length_ = 0;
226   kd_prf_ = "aes-ctr";
227 #endif
228   role_ = ROLE_LEFT;
229 }
230
231 Options::~Options()
232 {
233 }
234
235 #define NOTHING
236
237 #define PARSE_BOOL_PARAM(SHORT, LONG, VALUE, DO_POST)                           \
238     else if(str == SHORT || str == LONG) {                                      \
239       VALUE = true;                                                             \
240       DO_POST;                                                                  \
241     }
242
243 #define PARSE_INVERSE_BOOL_PARAM(SHORT, LONG, VALUE, DO_POST)                   \
244     else if(str == SHORT || str == LONG) {                                      \
245       VALUE = false;                                                            \
246       DO_POST;                                                                  \
247     }
248
249 #define PARSE_SIGNED_INT_PARAM(SHORT, LONG, VALUE, DO_POST)                     \
250     else if(str == SHORT || str == LONG)                                        \
251     {                                                                           \
252       if(argc < 1)                                                              \
253         throw syntax_error(str, str.length());                                  \
254       std::stringstream tmp;                                                    \
255       tmp << argv[i+1];                                                         \
256       tmp >> VALUE;                                                             \
257       argc--;                                                                   \
258       i++;                                                                      \
259       DO_POST;                                                                  \
260     }
261
262 #define PARSE_SCALAR_PARAM(SHORT, LONG, VALUE, DO_POST)                         \
263     else if(str == SHORT || str == LONG)                                        \
264     {                                                                           \
265       if(argc < 1)                                                              \
266         throw syntax_error(str, str.length());                                  \
267       if(argv[i+1][0] == '-') {                                                 \
268         uint32_t pos = str.length() + 1;                                       \
269         throw syntax_error(str.append(" ").append(argv[i+1]), pos);             \
270       }                                                                         \
271       std::stringstream tmp;                                                    \
272       tmp << argv[i+1];                                                         \
273       tmp >> VALUE;                                                             \
274       argc--;                                                                   \
275       i++;                                                                      \
276       DO_POST;                                                                  \
277     }
278
279 #define PARSE_SCALAR_PARAM2(SHORT, LONG, VALUE1, VALUE2, DO_POST)               \
280     else if(str == SHORT || str == LONG)                                        \
281     {                                                                           \
282       if(argc < 1)                                                              \
283         throw syntax_error(str, str.length());                                  \
284       if(argc < 2)                                                              \
285         throw syntax_error(str.append(" ").append(argv[i+1]), str.length());    \
286       if(argv[i+1][0] == '-') {                                                 \
287         uint32_t pos = str.length() + 1;                                       \
288         throw syntax_error(str.append(" ").append(argv[i+1]), pos);             \
289       }                                                                         \
290       if(argv[i+2][0] == '-') {                                                 \
291         uint32_t pos = str.length() + 1 + strlen(argv[i+1]) + 1;               \
292         throw syntax_error(str.append(" ").append(argv[i+1]).append(" ").append(argv[i+2]), pos); \
293       }                                                                         \
294       std::stringstream tmp;                                                    \
295       tmp << argv[i+1] << " " << argv[i+2];                                     \
296       tmp >> VALUE1;                                                            \
297       tmp >> VALUE2;                                                            \
298       argc-=2;                                                                  \
299       i+=2;                                                                     \
300       DO_POST;                                                                  \
301     }
302
303 #define PARSE_CSLIST_PARAM(SHORT, LONG, LIST, TYPE, DO_POST)                    \
304     else if(str == SHORT || str == LONG)                                        \
305     {                                                                           \
306       if(argc < 1)                                                              \
307         throw syntax_error(str, str.length());                                  \
308       if(argv[i+1][0] == '-') {                                                 \
309         uint32_t pos = str.length() + 1;                                       \
310         throw syntax_error(str.append(" ").append(argv[i+1]), pos);             \
311       }                                                                         \
312       std::stringstream tmp(argv[i+1]);                                         \
313       while (tmp.good())                                                        \
314       {                                                                         \
315         std::string tmp_line;                                                   \
316         getline(tmp,tmp_line,',');                                              \
317         LIST.push_back(TYPE(tmp_line));                                         \
318       }                                                                         \
319       argc--;                                                                   \
320       i++;                                                                      \
321       DO_POST;                                                                  \
322     }
323
324 #define PARSE_HEXSTRING_PARAM_SEC(SHORT, LONG, VALUE, DO_POST)                  \
325     else if(str == SHORT || str == LONG)                                        \
326     {                                                                           \
327       if(argc < 1)                                                              \
328         throw syntax_error(str, str.length());                                  \
329       if(argv[i+1][0] == '-') {                                                 \
330         uint32_t pos = str.length() + 1;                                       \
331         throw syntax_error(str.append(" ").append(argv[i+1]), pos);             \
332       }                                                                         \
333       VALUE = Buffer(std::string(argv[i+1]));                                   \
334       for(size_t j=0; j < strlen(argv[i+1]); ++j)                               \
335         argv[i+1][j] = '#';                                                     \
336       argc--;                                                                   \
337       i++;                                                                      \
338       DO_POST;                                                                  \
339     }
340
341 #define PARSE_PHRASE_PARAM_SEC(SHORT, LONG, VALUE, DO_POST)                     \
342     else if(str == SHORT || str == LONG)                                        \
343     {                                                                           \
344       if(argc < 1)                                                              \
345         throw syntax_error(str, str.length());                                  \
346       if(argv[i+1][0] == '-') {                                                 \
347         uint32_t pos = str.length() + 1;                                       \
348         throw syntax_error(str.append(" ").append(argv[i+1]), pos);             \
349       }                                                                         \
350       VALUE = argv[i+1];                                                        \
351       for(size_t j=0; j < strlen(argv[i+1]); ++j)                               \
352         argv[i+1][j] = '#';                                                     \
353       argc--;                                                                   \
354       i++;                                                                      \
355       DO_POST;                                                                  \
356     }
357
358 #define PARSE_STRING_LIST(SHORT, LONG, LIST, DO_POST)                           \
359     else if(str == SHORT || str == LONG)                                        \
360     {                                                                           \
361       if(argc < 1)                                                              \
362         throw syntax_error(str, str.length());                                  \
363       if(argv[i+1][0] == '-') {                                                 \
364         uint32_t pos = str.length() + 1;                                       \
365         throw syntax_error(str.append(" ").append(argv[i+1]), pos);             \
366       }                                                                         \
367       LIST.push_back(argv[i+1]);                                                \
368       argc--;                                                                   \
369       i++;                                                                      \
370       DO_POST;                                                                  \
371     }
372
373 bool Options::parse(int argc, char* argv[])
374 {
375   WritersLock lock(mutex);
376
377   progname_ = argv[0];
378   argc--;
379   bool ipv4_only = false, ipv6_only = false;
380   std::string role = "";
381   for(int i=1; argc > 0; ++i) {
382     std::string str(argv[i]);
383     argc--;
384
385     if(str == "-h" || str == "--help") {
386       printUsage();
387       return false;
388     } else if(str == "-v" || str == "--version") {
389       printVersion();
390       return false;
391     }
392
393 #if defined(ANYTUN_OPTIONS) || defined(ANYCTR_OPTIONS)
394
395 #ifndef _MSC_VER
396     PARSE_INVERSE_BOOL_PARAM("-D","--nodaemonize", daemonize_, NOTHING)
397     PARSE_SCALAR_PARAM("-u","--username", username_, NOTHING)
398     PARSE_SCALAR_PARAM("-g","--groupname", groupname_, NOTHING)
399     PARSE_SCALAR_PARAM("-C","--chroot", chroot_dir_, NOTHING)
400     PARSE_SCALAR_PARAM("-P","--write-pid", pid_file_, NOTHING)
401 #endif
402
403 #endif
404
405     PARSE_STRING_LIST("-L","--log", log_targets_, NOTHING)
406     PARSE_BOOL_PARAM("-U","--debug", debug_, NOTHING)
407
408 #if defined(ANYCTR_OPTIONS)
409
410     PARSE_SCALAR_PARAM("-f","--file", file_name_, NOTHING)
411     PARSE_SCALAR_PARAM("-X","--control-host", bind_to_, NOTHING)
412
413 #endif
414 #if defined(ANYTUN_OPTIONS)
415
416     PARSE_SCALAR_PARAM("-i","--interface", local_.addr, NOTHING)
417     PARSE_SCALAR_PARAM("-p","--port", local_.port, NOTHING)
418     PARSE_SCALAR_PARAM("-s","--sender-id", sender_id_, NOTHING)
419
420 #endif
421 #if defined(ANYTUN_OPTIONS) || defined(ANYCONF_OPTIONS)
422
423     PARSE_SCALAR_PARAM("-r","--remote-host", remote_.addr, connection_opts = true)
424     PARSE_SCALAR_PARAM("-o","--remote-port", remote_.port, connection_opts = true)
425     PARSE_BOOL_PARAM("-4","--ipv4-only", ipv4_only, connection_opts = true)
426     PARSE_BOOL_PARAM("-6","--ipv6-only", ipv6_only, connection_opts = true)
427
428 #endif
429 #if defined(ANYTUN_OPTIONS)
430
431     PARSE_SCALAR_PARAM("-I","--sync-interface", local_sync_.addr, cluster_opts = true)
432     PARSE_SCALAR_PARAM("-S","--sync-port", local_sync_.port, cluster_opts = true)
433     PARSE_CSLIST_PARAM("-M","--sync-hosts", remote_sync_hosts_, OptionHost, cluster_opts = true)
434     PARSE_CSLIST_PARAM("-X","--control-host", remote_sync_hosts_, OptionHost, cluster_opts = true)
435
436     PARSE_SCALAR_PARAM("-d","--dev", dev_name_, NOTHING)
437     PARSE_SCALAR_PARAM("-t","--type", dev_type_, NOTHING)
438     PARSE_SCALAR_PARAM("-n","--ifconfig", ifconfig_param_, NOTHING)
439     PARSE_SCALAR_PARAM("-x","--post-up-script", post_up_script_, NOTHING)
440
441 #endif
442 #if defined(ANYTUN_OPTIONS) || defined(ANYCONF_OPTIONS)
443
444 #ifndef NO_ROUTING
445     PARSE_CSLIST_PARAM("-R","--route", routes_, OptionNetwork, connection_opts = true)
446 #endif
447
448     PARSE_SCALAR_PARAM("-m","--mux", mux_, connection_opts = true)
449     PARSE_SCALAR_PARAM("-w","--window-size", seq_window_size_, connection_opts = true)
450
451 #ifndef NO_CRYPT
452     PARSE_SCALAR_PARAM("-k","--kd-prf", kd_prf_, connection_opts = true)
453     PARSE_SCALAR_PARAM("-e","--role", role, connection_opts = true)
454 #ifndef NO_PASSPHRASE
455     PARSE_PHRASE_PARAM_SEC("-E","--passphrase", passphrase_, connection_opts = true)
456 #endif
457     PARSE_HEXSTRING_PARAM_SEC("-K","--key", key_, connection_opts = true)
458     PARSE_HEXSTRING_PARAM_SEC("-A","--salt", salt_, connection_opts = true)
459 #endif
460
461 #endif
462 #if defined(ANYTUN_OPTIONS)
463
464 #ifndef NO_CRYPT
465     PARSE_SCALAR_PARAM("-c","--cipher", cipher_, NOTHING)
466     PARSE_SCALAR_PARAM("-a","--auth-algo", auth_algo_, NOTHING)
467     PARSE_SCALAR_PARAM("-b","--auth-tag-length", auth_tag_length_, NOTHING)
468 #endif
469
470 #endif
471     else {
472       throw syntax_error(str, 0);
473     }
474   }
475   if(ipv4_only && ipv6_only) {
476     throw syntax_error("-4 and -6 are mutual exclusive", -1);
477   }
478   if(ipv4_only) {
479     resolv_addr_type_ = IPV4_ONLY;
480   }
481   if(ipv6_only) {
482     resolv_addr_type_ = IPV6_ONLY;
483   }
484
485   if(role != "") {
486     if(role == "alice" || role == "server" || role == "left") {
487       role_ = ROLE_LEFT;
488     } else if(role == "bob" || role == "client" || role == "right") {
489       role_ = ROLE_RIGHT;
490     } else {
491       throw syntax_error("unknown role name: " + role, -1);
492     }
493   }
494
495   if(debug_) {
496     log_targets_.push_back("stdout:5");
497     daemonize_ = false;
498   }
499
500   if(log_targets_.empty()) {
501 #ifndef _MSC_VER
502 #if !defined(ANYCONF_OPTIONS)
503     log_targets_.push_back(std::string("syslog:3,").append(progname_).append(",daemon"));
504 #else
505     log_targets_.push_back("stderr:2");
506 #endif
507 #else
508 #ifdef WIN_SERVICE
509     log_targets_.push_back(std::string("eventlog:3,").append(progname_));
510 #else
511     log_targets_.push_back("stdout:3");
512 #endif
513 #endif
514   }
515
516   return true;
517 }
518
519 void Options::parse_post()
520 {
521 #if defined(ANYTUN_OPTIONS)
522   if(cluster_opts && connection_opts) {
523     cLog.msg(Log::PRIO_WARNING) << "you have provided options for cluster support as well as connection oriented options, we strongly recommend to use anytun-config and anytun-controld when building a cluster";
524   }
525
526   if(cipher_ == "null" && auth_algo_ == "null") {
527     kd_prf_ = "null";
528   }
529   if((cipher_ != "null" || auth_algo_ != "null") && kd_prf_ == "null") {
530     cLog.msg(Log::PRIO_WARNING) << "using NULL key derivation with encryption and or authentication enabled!";
531   }
532
533   uint32_t tag_len_max = AuthAlgoFactory::getDigestLength(auth_algo_);
534   if(!tag_len_max) { auth_tag_length_ = 0; }
535   else if(tag_len_max < auth_tag_length_) {
536     cLog.msg(Log::PRIO_WARNING) << auth_algo_ << " auth algo can't generate tags of length " << auth_tag_length_ << ", using maximum tag length(" << tag_len_max << ")";
537     auth_tag_length_ = tag_len_max;
538   }
539 #endif
540
541   if(dev_name_ == "" && dev_type_ == "") {
542     dev_type_ = "tun";
543   }
544 }
545
546 void Options::printVersion()
547 {
548 #if defined(ANYCTR_OPTIONS)
549   std::cout << "anytun-controld";
550 #elif defined(ANYCONF_OPTIONS)
551   std::cout << "anytun-config";
552 #else
553   std::cout << "anytun";
554 #endif
555   std::cout << VERSION_STRING_0 << std::endl;
556   std::cout << VERSION_STRING_1 << std::endl;
557 }
558
559 void Options::printUsage()
560 {
561   std::cout << "USAGE:" << std::endl;
562
563 #if defined(ANYCTR_OPTIONS)
564   std::cout << "anytun-controld " << std::endl;
565 #elif defined(ANYCONF_OPTIONS)
566   std::cout << "anytun-config " << std::endl;
567 #else
568   std::cout << "anytun " << std::endl;
569 #endif
570
571   std::cout << "   [-h|--help]                         prints this..." << std::endl;
572   std::cout << "   [-v|--version]                      print version info and exit" << std::endl;
573
574 #if defined(ANYTUN_OPTIONS) || defined(ANYCTR_OPTIONS)
575
576 #ifndef _MSC_VER
577   std::cout << "   [-D|--nodaemonize]                  don't run in background" << std::endl;
578   std::cout << "   [-u|--username] <username>          change to this user" << std::endl;
579   std::cout << "   [-g|--groupname] <groupname>        change to this group" << std::endl;
580   std::cout << "   [-C|--chroot] <path>                chroot to this directory" << std::endl;
581   std::cout << "   [-P|--write-pid] <path>             write pid to this file" << std::endl;
582 #endif
583
584 #endif
585
586   std::cout << "   [-L|--log] <target>:<level>[,<param1>[,<param2>..]]" << std::endl;
587   std::cout << "                                       add a log target, can be invoked several times" << std::endl;
588   std::cout << "                                       i.e.: stdout:5" << std::endl;
589   std::cout << "   [-U|--debug]                        don't daemonize and log to stdout with maximum log level" << std::endl;
590
591 #if defined(ANYCTR_OPTIONS)
592
593   std::cout << "   [-f|--file] <path>                  path to input file" << std::endl;
594   std::cout << "   [-X|--control-host] < <hostname|ip>[:<port>] | :<port> >" << std::endl;
595   std::cout << "                                       local tcp port and or ip address to bind to" << std::endl;
596
597 #endif
598 #if defined(ANYTUN_OPTIONS)
599
600   std::cout << "   [-i|--interface] <hostname|ip>      local anycast ip address to bind to" << std::endl;
601   std::cout << "   [-p|--port] <port>                  local anycast(data) port to bind to" << std::endl;
602   std::cout << "   [-s|--sender-id ] <sender id>       the sender id to use" << std::endl;
603
604 #endif
605 #if defined(ANYTUN_OPTIONS) || defined(ANYCONF_OPTIONS)
606
607   std::cout << "   [-r|--remote-host] <hostname|ip>    remote host" << std::endl;
608   std::cout << "   [-o|--remote-port] <port>           remote port" << std::endl;
609   std::cout << "   [-4|--ipv4-only]                    always resolv IPv4 addresses" << std::endl;
610   std::cout << "   [-6|--ipv6-only]                    always resolv IPv6 addresses" << std::endl;
611
612 #endif
613 #if defined(ANYTUN_OPTIONS)
614
615   std::cout << "   [-I|--sync-interface] <ip-address>  local unicast(sync) ip address to bind to" << std::endl;
616   std::cout << "   [-S|--sync-port] <port>             local unicast(sync) port to bind to" << std::endl;
617   std::cout << "   [-M|--sync-hosts] <hostname|ip>[:<port>][,<hostname|ip>[:<port>][...]]"<< std::endl;
618   std::cout << "                                       remote hosts to sync with" << std::endl;
619   std::cout << "   [-X|--control-host] <hostname|ip>[:<port>]"<< std::endl;
620   std::cout << "                                       fetch the config from this host" << std::endl;
621
622   std::cout << "   [-d|--dev] <name>                   device name" << std::endl;
623   std::cout << "   [-t|--type] <tun|tap>               device type" << std::endl;
624   std::cout << "   [-n|--ifconfig] <local>/<prefix>    the local address for the tun/tap device and the used prefix length" << std::endl;
625   std::cout << "   [-x|--post-up-script] <script>      script gets called after interface is created" << std::endl;
626
627 #endif
628 #if defined(ANYTUN_OPTIONS) || defined(ANYCONF_OPTIONS)
629
630 #ifndef NO_ROUTING
631   std::cout << "   [-R|--route] <net>/<prefix length>  add a route to connection, can be invoked several times" << std::endl;
632 #endif
633
634   std::cout << "   [-m|--mux] <mux-id>                 the multiplex id to use" << std::endl;
635   std::cout << "   [-w|--window-size] <window size>    seqence number window size" << std::endl;
636
637 #ifndef NO_CRYPT
638   std::cout << "   [-k|--kd-prf] <kd-prf type>         key derivation pseudo random function" << std::endl;
639   std::cout << "   [-e|--role] <role>                  left (alice) or right (bob)" << std::endl;
640 #ifndef NO_PASSPHRASE
641   std::cout << "   [-E|--passphrase] <pass phrase>     a passprhase to generate master key and salt from" << std::endl;
642 #endif
643   std::cout << "   [-K|--key] <master key>             master key to use for encryption" << std::endl;
644   std::cout << "   [-A|--salt] <master salt>           master salt to use for encryption" << std::endl;
645 #endif
646
647 #endif
648 #if defined(ANYTUN_OPTIONS)
649
650 #ifndef NO_CRYPT
651   std::cout << "   [-c|--cipher] <cipher type>         payload encryption algorithm" << std::endl;
652   std::cout << "   [-a|--auth-algo] <algo type>        message authentication algorithm" << std::endl;
653   std::cout << "   [-b|--auth-tag-length]              length of the auth tag" << std::endl;
654 #endif
655
656 #endif
657 }
658
659 void Options::printOptions()
660 {
661   ReadersLock lock(mutex);
662
663   std::cout << "Options:" << std::endl;
664   std::cout << std::endl;
665   std::cout << "daemonize = " << daemonize_ << std::endl;
666   std::cout << "username = '" << username_ << "'" << std::endl;
667   std::cout << "groupname = '" << groupname_ << "'" << std::endl;
668   std::cout << "chroot_dir = '" << chroot_dir_ << "'" << std::endl;
669   std::cout << "pid_file = '" << pid_file_ << "'" << std::endl;
670   std::cout << std::endl;
671   std::cout << "log_targets:";
672   StringList::const_iterator lit = log_targets_.begin();
673   for(; lit != log_targets_.end(); ++lit) {
674     std::cout << " '" << *lit << "',";
675   }
676   std::cout << std::endl;
677   std::cout << "debug = " << debug_ << std::endl;
678   std::cout << std::endl;
679   std::cout << "file_name = '" << file_name_ << "'" << std::endl;
680   std::cout << "bind_to.addr = '" << bind_to_.addr << "'" << std::endl;
681   std::cout << "bind_to.port = '" << bind_to_.port << "'" << std::endl;
682   std::cout << std::endl;
683   std::cout << "resolv_addr_type = ";
684   switch(resolv_addr_type_) {
685   case ANY:
686     std::cout <<  "any" << std::endl;
687     break;
688   case IPV4_ONLY:
689     std::cout <<  "ipv4-only" << std::endl;
690     break;
691   case IPV6_ONLY:
692     std::cout <<  "ipv6-only" << std::endl;
693     break;
694   default:
695     std::cout <<  "?" << std::endl;
696     break;
697   }
698   std::cout << std::endl;
699   std::cout << "local.addr = '" << local_.addr << "'" << std::endl;
700   std::cout << "local.port = '" << local_.port << "'" << std::endl;
701   std::cout << "remote.addr = '" << remote_.addr << "'" << std::endl;
702   std::cout << "remote.port = '" << remote_.port << "'" << std::endl;
703   std::cout << "local_sync.addr = '" << local_sync_.addr << "'" << std::endl;
704   std::cout << "local_sync.port = '" << local_sync_.port << "'" << std::endl;
705   std::cout << "remote_sync_hosts:" << std::endl;
706   HostList::const_iterator hit = remote_sync_hosts_.begin();
707   for(; hit != remote_sync_hosts_.end(); ++hit) {
708     std::cout << "  '" << hit->addr << "','" << hit->port << "'" << std::endl;
709   }
710   std::cout << std::endl;
711   std::cout << "dev_name = '" << dev_name_ << "'" << std::endl;
712   std::cout << "dev_type = '" << dev_type_ << "'" << std::endl;
713   std::cout << "ifconfig_param_local = '" << ifconfig_param_.net_addr << "/" << ifconfig_param_.prefix_length << "'" << std::endl;
714   std::cout << "post_up_script = '" << post_up_script_ << "'" << std::endl;
715   std::cout << "routes:" << std::endl;
716   NetworkList::const_iterator rit;
717   for(rit = routes_.begin(); rit != routes_.end(); ++rit) {
718     std::cout << "  " << rit->net_addr << "/" << rit->prefix_length << std::endl;
719   }
720   std::cout << std::endl;
721   std::cout << "sender_id = '" << sender_id_ << "'" << std::endl;
722   std::cout << "mux_id = " << mux_ << std::endl;
723   std::cout << "seq_window_size = '" << seq_window_size_ << "'" << std::endl;
724   std::cout << std::endl;
725   std::cout << "cipher = '" << cipher_ << "'" << std::endl;
726   std::cout << "auth_algo = '" << auth_algo_ << "'" << std::endl;
727   std::cout << "auth_tag_length = " << auth_tag_length_ << std::endl;
728   std::cout << "kd_prf = '" << kd_prf_ << "'" << std::endl;
729   std::cout << "role = ";
730   switch(role_) {
731   case ROLE_LEFT:
732     std::cout << "left" << std::endl;
733     break;
734   case ROLE_RIGHT:
735     std::cout << "right" << std::endl;
736     break;
737   default:
738     std::cout << "??" << std::endl;
739     break;
740   }
741   std::cout << "passphrase = '" << passphrase_ << "'" << std::endl;
742   std::cout << "key = " << key_.getHexDumpOneLine() << std::endl;
743   std::cout << "salt = " << salt_.getHexDumpOneLine() << std::endl;
744 }
745
746
747
748 std::string Options::getProgname()
749 {
750   ReadersLock lock(mutex);
751   return progname_;
752 }
753
754 Options& Options::setProgname(std::string p)
755 {
756   WritersLock lock(mutex);
757   progname_ = p;
758   return *this;
759 }
760
761 bool Options::getDaemonize()
762 {
763   ReadersLock lock(mutex);
764   return daemonize_;
765 }
766
767 Options& Options::setDaemonize(bool d)
768 {
769   WritersLock lock(mutex);
770   daemonize_ = d;
771   return *this;
772 }
773
774 std::string Options::getUsername()
775 {
776   ReadersLock lock(mutex);
777   return username_;
778 }
779
780 Options& Options::setUsername(std::string u)
781 {
782   WritersLock lock(mutex);
783   username_ = u;
784   return *this;
785 }
786
787 std::string Options::getGroupname()
788 {
789   ReadersLock lock(mutex);
790   return groupname_;
791 }
792
793 Options& Options::setGroupname(std::string g)
794 {
795   WritersLock lock(mutex);
796   groupname_ = g;
797   return *this;
798 }
799
800 std::string Options::getChrootDir()
801 {
802   ReadersLock lock(mutex);
803   return chroot_dir_;
804 }
805
806 Options& Options::setChrootDir(std::string c)
807 {
808   WritersLock lock(mutex);
809   chroot_dir_ = c;
810   return *this;
811 }
812
813 std::string Options::getPidFile()
814 {
815   ReadersLock lock(mutex);
816   return pid_file_;
817 }
818
819 Options& Options::setPidFile(std::string p)
820 {
821   WritersLock lock(mutex);
822   pid_file_ = p;
823   return *this;
824 }
825
826
827 StringList Options::getLogTargets()
828 {
829   ReadersLock lock(mutex);
830   return log_targets_;
831 }
832
833 bool Options::getDebug()
834 {
835   ReadersLock lock(mutex);
836   return debug_;
837 }
838
839 Options& Options::setDebug(bool d)
840 {
841   WritersLock lock(mutex);
842   debug_ = d;
843   return *this;
844 }
845
846
847 std::string Options::getFileName()
848 {
849   ReadersLock lock(mutex);
850   return file_name_;
851 }
852
853 Options& Options::setFileName(std::string f)
854 {
855   WritersLock lock(mutex);
856   file_name_ = f;
857   return *this;
858 }
859
860 std::string Options::getBindToAddr()
861 {
862   ReadersLock lock(mutex);
863   return bind_to_.addr;
864 }
865
866 Options& Options::setBindToAddr(std::string b)
867 {
868   WritersLock lock(mutex);
869   bind_to_.addr = b;
870   return *this;
871 }
872
873 std::string Options::getBindToPort()
874 {
875   ReadersLock lock(mutex);
876   return bind_to_.port;
877 }
878
879 Options& Options::setBindToPort(std::string b)
880 {
881   WritersLock lock(mutex);
882   bind_to_.port = b;
883   return *this;
884 }
885
886
887 ResolvAddrType Options::getResolvAddrType()
888 {
889   ReadersLock lock(mutex);
890   return resolv_addr_type_;
891 }
892
893 Options& Options::setResolvAddrType(ResolvAddrType r)
894 {
895   WritersLock lock(mutex);
896   resolv_addr_type_ = r;
897   return *this;
898 }
899
900 std::string Options::getLocalAddr()
901 {
902   ReadersLock lock(mutex);
903   return local_.addr;
904 }
905
906 Options& Options::setLocalAddr(std::string l)
907 {
908   WritersLock lock(mutex);
909   local_.addr = l;
910   return *this;
911 }
912
913 std::string Options::getLocalPort()
914 {
915   ReadersLock lock(mutex);
916   return local_.port;
917 }
918
919 Options& Options::setLocalPort(std::string l)
920 {
921   WritersLock lock(mutex);
922   local_.port = l;
923   return *this;
924 }
925
926 std::string Options::getRemoteAddr()
927 {
928   ReadersLock lock(mutex);
929   return remote_.addr;
930 }
931
932 Options& Options::setRemoteAddr(std::string r)
933 {
934   WritersLock lock(mutex);
935   remote_.addr = r;
936   return *this;
937 }
938
939 std::string Options::getRemotePort()
940 {
941   ReadersLock lock(mutex);
942   return remote_.port;
943 }
944
945 Options& Options::setRemotePort(std::string r)
946 {
947   WritersLock lock(mutex);
948   remote_.port = r;
949   return *this;
950 }
951
952 std::string Options::getLocalSyncAddr()
953 {
954   ReadersLock lock(mutex);
955   return local_sync_.addr;
956 }
957
958 Options& Options::setLocalSyncAddr(std::string l)
959 {
960   WritersLock lock(mutex);
961   local_sync_.addr = l;
962   return *this;
963 }
964
965 std::string Options::getLocalSyncPort()
966 {
967   ReadersLock lock(mutex);
968   return local_sync_.port;
969 }
970
971 Options& Options::setLocalSyncPort(std::string l)
972 {
973   WritersLock lock(mutex);
974   local_sync_.port = l;
975   return *this;
976 }
977
978 HostList Options::getRemoteSyncHosts()
979 {
980   ReadersLock lock(mutex);
981   return remote_sync_hosts_;
982 }
983
984
985
986 std::string Options::getDevName()
987 {
988   ReadersLock lock(mutex);
989   return dev_name_;
990 }
991
992 Options& Options::setDevName(std::string d)
993 {
994   WritersLock lock(mutex);
995   dev_name_ = d;
996   return *this;
997 }
998
999 std::string Options::getDevType()
1000 {
1001   ReadersLock lock(mutex);
1002   return dev_type_;
1003 }
1004
1005 Options& Options::setDevType(std::string d)
1006 {
1007   WritersLock lock(mutex);
1008   dev_type_ = d;
1009   return *this;
1010 }
1011
1012 OptionNetwork Options::getIfconfigParam()
1013 {
1014   ReadersLock lock(mutex);
1015   return ifconfig_param_;
1016 }
1017
1018 Options& Options::setIfconfigParam(OptionNetwork i)
1019 {
1020   WritersLock lock(mutex);
1021   ifconfig_param_ = i;
1022   return *this;
1023 }
1024
1025 std::string Options::getPostUpScript()
1026 {
1027   ReadersLock lock(mutex);
1028   return post_up_script_;
1029 }
1030
1031 Options& Options::setPostUpScript(std::string p)
1032 {
1033   WritersLock lock(mutex);
1034   post_up_script_ = p;
1035   return *this;
1036 }
1037
1038 NetworkList Options::getRoutes()
1039 {
1040   ReadersLock lock(mutex);
1041   return routes_;
1042 }
1043
1044
1045
1046 sender_id_t Options::getSenderId()
1047 {
1048   ReadersLock lock(mutex);
1049   return sender_id_;
1050 }
1051
1052 Options& Options::setSenderId(sender_id_t s)
1053 {
1054   WritersLock lock(mutex);
1055   sender_id_ = s;
1056   return *this;
1057 }
1058
1059 mux_t Options::getMux()
1060 {
1061   ReadersLock lock(mutex);
1062   return mux_;
1063 }
1064
1065 Options& Options::setMux(mux_t m)
1066 {
1067   WritersLock lock(mutex);
1068   mux_ = m;
1069   return *this;
1070 }
1071
1072 window_size_t Options::getSeqWindowSize()
1073 {
1074   ReadersLock lock(mutex);
1075   return seq_window_size_;
1076 }
1077
1078 Options& Options::setSeqWindowSize(window_size_t s)
1079 {
1080   WritersLock lock(mutex);
1081   seq_window_size_ = s;
1082   return *this;
1083 }
1084
1085
1086
1087 std::string Options::getCipher()
1088 {
1089   ReadersLock lock(mutex);
1090   return cipher_;
1091 }
1092
1093 Options& Options::setCipher(std::string c)
1094 {
1095   WritersLock lock(mutex);
1096   cipher_ = c;
1097   return *this;
1098 }
1099
1100 std::string Options::getAuthAlgo()
1101 {
1102   ReadersLock lock(mutex);
1103   return auth_algo_;
1104 }
1105
1106 Options& Options::setAuthAlgo(std::string a)
1107 {
1108   WritersLock lock(mutex);
1109   auth_algo_ = a;
1110   return *this;
1111 }
1112
1113 uint32_t Options::getAuthTagLength()
1114 {
1115   ReadersLock lock(mutex);
1116   return auth_tag_length_;
1117 }
1118
1119 Options& Options::setAuthTagLength(uint32_t a)
1120 {
1121   WritersLock lock(mutex);
1122   auth_tag_length_ = a;
1123   return *this;
1124 }
1125
1126
1127 std::string Options::getKdPrf()
1128 {
1129   ReadersLock lock(mutex);
1130   return kd_prf_;
1131 }
1132
1133 Options& Options::setKdPrf(std::string k)
1134 {
1135   WritersLock lock(mutex);
1136   kd_prf_ = k;
1137   return *this;
1138 }
1139
1140 role_t Options::getRole()
1141 {
1142   ReadersLock lock(mutex);
1143   return role_;
1144 }
1145
1146 Options& Options::setRole(role_t r)
1147 {
1148   WritersLock lock(mutex);
1149   role_ = r;
1150   return *this;
1151 }
1152
1153 std::string Options::getPassphrase()
1154 {
1155   ReadersLock lock(mutex);
1156   return passphrase_;
1157 }
1158
1159 Options& Options::setPassphrase(std::string p)
1160 {
1161   WritersLock lock(mutex);
1162   passphrase_ = p;
1163   return *this;
1164 }
1165
1166 Buffer Options::getKey()
1167 {
1168   ReadersLock lock(mutex);
1169   return key_;
1170 }
1171
1172 Options& Options::setKey(std::string k)
1173 {
1174   WritersLock lock(mutex);
1175   key_ = k;
1176   return *this;
1177 }
1178
1179 Buffer Options::getSalt()
1180 {
1181   ReadersLock lock(mutex);
1182   return salt_;
1183 }
1184
1185 Options& Options::setSalt(std::string s)
1186 {
1187   WritersLock lock(mutex);
1188   salt_ = s;
1189   return *this;
1190 }