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