anyrtpproxy: commandhanlder uses now boost::asio and boost::thread
[anytun.git] / src / options.cpp
blob4bf4ef7f155aff26c1b04a1404d218c2b3f0d9b2
1 /*
2 * anytun
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.
14 * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl,
15 * Christian Pointner <satp@wirdorange.org>
17 * This file is part of Anytun.
19 * Anytun is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License version 3 as
21 * published by the Free Software Foundation.
23 * Anytun is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with anytun. If not, see <http://www.gnu.org/licenses/>.
32 #include <iostream>
33 #include <queue>
34 #include <string>
35 #include <sstream>
36 #include <cstring>
38 #include "datatypes.h"
39 #include "options.h"
41 Options* Options::inst = NULL;
42 Mutex Options::instMutex;
43 Options& gOpt = Options::instance();
45 Options& Options::instance()
47 Lock lock(instMutex);
48 static instanceCleaner c;
49 if(!inst)
50 inst = new Options();
52 return *inst;
55 Options::Options() : key_(u_int32_t(0)), salt_(u_int32_t(0))
57 progname_ = "anytun";
58 daemonize_ = true;
59 chroot_ = false;
60 username_ = "nobody";
61 chroot_dir_ = "/var/run/anytun";
62 pid_file_ = "";
63 sender_id_ = 0;
64 local_addr_ = "";
65 local_port_ = "4444";
66 local_sync_port_ = "";
67 remote_sync_port_ = "";
68 remote_sync_addr_ = "";
69 remote_addr_ = "";
70 remote_port_ = "4444";
71 dev_name_ = "";
72 dev_type_ = "";
73 ifconfig_param_local_ = "";
74 ifconfig_param_remote_netmask_ = "";
75 post_up_script_ = "";
76 seq_window_size_ = 100;
77 cipher_ = "aes-ctr";
78 kd_prf_ = "aes-ctr";
79 auth_algo_ = "sha1";
80 mux_ = 0;
83 Options::~Options()
87 #define PARSE_BOOL_PARAM(SHORT, LONG, VALUE) \
88 else if(str == SHORT || str == LONG) \
89 VALUE = true;
91 #define PARSE_INVERSE_BOOL_PARAM(SHORT, LONG, VALUE) \
92 else if(str == SHORT || str == LONG) \
93 VALUE = false;
95 #define PARSE_SCALAR_PARAM(SHORT, LONG, VALUE) \
96 else if(str == SHORT || str == LONG) \
97 { \
98 if(argc < 1 || argv[i+1][0] == '-') \
99 return false; \
100 std::stringstream tmp; \
101 tmp << argv[i+1]; \
102 tmp >> VALUE; \
103 argc--; \
104 i++; \
107 #define PARSE_SCALAR_PARAM2(SHORT, LONG, VALUE1, VALUE2) \
108 else if(str == SHORT || str == LONG) \
110 if(argc < 2 || \
111 argv[i+1][0] == '-' || argv[i+2][0] == '-') \
112 return false; \
113 std::stringstream tmp; \
114 tmp << argv[i+1] << " " << argv[i+2]; \
115 tmp >> VALUE1; \
116 tmp >> VALUE2; \
117 argc-=2; \
118 i+=2; \
121 #define PARSE_HEXSTRING_PARAM_SEC(SHORT, LONG, VALUE) \
122 else if(str == SHORT || str == LONG) \
124 if(argc < 1 || argv[i+1][0] == '-') \
125 return false; \
126 VALUE = Buffer(std::string(argv[i+1])); \
127 for(size_t j=0; j < strlen(argv[i+1]); ++j) \
128 argv[i+1][j] = '#'; \
129 argc--; \
130 i++; \
133 #define PARSE_CSLIST_PARAM(SHORT, LONG, LIST) \
134 else if(str == SHORT || str == LONG) \
136 if(argc < 1 || argv[i+1][0] == '-') \
137 return false; \
138 std::stringstream tmp(argv[i+1]); \
139 while (tmp.good()) \
141 std::string tmp_line; \
142 getline(tmp,tmp_line,','); \
143 LIST.push(tmp_line); \
145 argc--; \
146 i++; \
149 bool Options::parse(int argc, char* argv[])
151 Lock lock(mutex);
153 progname_ = argv[0];
154 argc--;
155 std::queue<std::string> host_port_queue;
156 for(int i=1; argc > 0; ++i)
158 std::string str(argv[i]);
159 argc--;
161 if(str == "-h" || str == "--help")
162 return false;
163 PARSE_INVERSE_BOOL_PARAM("-D","--nodaemonize", daemonize_)
164 PARSE_BOOL_PARAM("-C","--chroot", chroot_)
165 PARSE_SCALAR_PARAM("-u","--username", username_)
166 PARSE_SCALAR_PARAM("-H","--chroot-dir", chroot_dir_)
167 PARSE_SCALAR_PARAM("-P","--write-pid", pid_file_)
168 PARSE_SCALAR_PARAM("-s","--sender-id", sender_id_)
169 PARSE_SCALAR_PARAM("-i","--interface", local_addr_)
170 PARSE_SCALAR_PARAM("-p","--port", local_port_)
171 PARSE_SCALAR_PARAM("-S","--sync-port", local_sync_port_)
172 PARSE_SCALAR_PARAM("-I","--sync-interface", local_sync_addr_)
173 PARSE_SCALAR_PARAM("-R","--remote-sync-host", remote_sync_addr_)
174 PARSE_SCALAR_PARAM("-O","--remote-sync-port", remote_sync_port_)
175 PARSE_SCALAR_PARAM("-r","--remote-host", remote_addr_)
176 PARSE_SCALAR_PARAM("-o","--remote-port", remote_port_)
177 PARSE_SCALAR_PARAM("-d","--dev", dev_name_)
178 PARSE_SCALAR_PARAM("-t","--type", dev_type_)
179 PARSE_SCALAR_PARAM2("-n","--ifconfig", ifconfig_param_local_, ifconfig_param_remote_netmask_)
180 PARSE_SCALAR_PARAM("-x","--post-up-script", post_up_script_)
181 PARSE_SCALAR_PARAM("-w","--window-size", seq_window_size_)
182 PARSE_SCALAR_PARAM("-m","--mux", mux_)
183 PARSE_SCALAR_PARAM("-c","--cipher", cipher_)
184 PARSE_HEXSTRING_PARAM_SEC("-K","--key", key_)
185 PARSE_HEXSTRING_PARAM_SEC("-A","--salt", salt_)
186 PARSE_SCALAR_PARAM("-k","--kd-prf", kd_prf_)
187 PARSE_SCALAR_PARAM("-a","--auth-algo", auth_algo_)
188 PARSE_CSLIST_PARAM("-M","--sync-hosts", host_port_queue)
189 PARSE_CSLIST_PARAM("-X","--control-host", host_port_queue)
190 else
191 return false;
194 if(cipher_ == "null" && auth_algo_ == "null")
195 kd_prf_ = "null";
196 if((cipher_ != "null" || auth_algo_ != "null") && kd_prf_ == "null")
197 kd_prf_ = "aes-ctr";
199 if(dev_name_ == "" && dev_type_ == "")
200 dev_type_ = "tun";
202 while(!host_port_queue.empty())
204 bool ret = splitAndAddHostPort(host_port_queue.front(), connect_to_);
205 if(!ret) return false;
206 host_port_queue.pop();
208 return true;
211 bool Options::splitAndAddHostPort(std::string hostPort, ConnectToList& list)
213 OptionConnectTo oct;
214 size_t pos = hostPort.find_first_of("[");
216 if(pos != std::string::npos && pos != 0)
217 return false; // an [ was found but not at the beginning
219 bool hasPort = false;
220 if(pos != std::string::npos) {
221 hostPort.erase(pos, 1);
222 pos = hostPort.find_first_of("]");
224 if(pos == std::string::npos)
225 return false; // no trailing ] although an leading [ was found
227 if(pos < hostPort.length()-2) {
229 if(hostPort[pos+1] != ':')
230 return false; // wrong port delimieter
232 hostPort[pos+1] = '/';
233 hasPort = true;
235 else if(pos != hostPort.length()-1)
236 return false; // to few characters left
238 hostPort.erase(pos, 1);
241 if(hasPort) {
242 std::stringstream tmp_stream(hostPort);
243 getline(tmp_stream,oct.host,'/');
244 if(!tmp_stream.good())
245 return false;
247 tmp_stream >> oct.port;
249 else {
250 oct.host = hostPort;
251 oct.port = "2323"; // default sync port
254 list.push_back(oct);
255 return true;
258 void Options::printUsage()
260 std::cout << "USAGE:" << std::endl;
261 std::cout << "anytun [-h|--help] prints this..." << std::endl;
262 // std::cout << " [-f|--config] <file> the config file" << std::endl;
263 std::cout << " [-D|--nodaemonize] don't run in background" << std::endl;
264 std::cout << " [-C|--chroot] chroot and drop privileges" << std::endl;
265 std::cout << " [-u|--username] <username> if chroot change to this user" << std::endl;
266 std::cout << " [-H|--chroot-dir] <path> chroot to this directory" << std::endl;
267 std::cout << " [-P|--write-pid] <path> write pid to this file" << std::endl;
268 std::cout << " [-s|--sender-id ] <sender id> the sender id to use" << std::endl;
269 std::cout << " [-i|--interface] <ip-address> local anycast ip address to bind to" << std::endl;
270 std::cout << " [-p|--port] <port> local anycast(data) port to bind to" << std::endl;
271 std::cout << " [-I|--sync-interface] <ip-address> local unicast(sync) ip address to bind to" << std::endl;
272 std::cout << " [-S|--sync-port] <port> local unicast(sync) port to bind to" << std::endl;
273 std::cout << " [-M|--sync-hosts] <hostname|ip>[:<port>][,<hostname|ip>[:<port>][...]]"<< std::endl;
274 std::cout << " remote hosts to sync with" << std::endl;
275 std::cout << " [-X|--control-host] <hostname|ip>[:<port>]"<< std::endl;
276 std::cout << " fetch the config from this host" << std::endl;
277 std::cout << " [-r|--remote-host] <hostname|ip> remote host" << std::endl;
278 std::cout << " [-o|--remote-port] <port> remote port" << std::endl;
279 std::cout << " [-d|--dev] <name> device name" << std::endl;
280 std::cout << " [-t|--type] <tun|tap> device type" << std::endl;
281 std::cout << " [-n|--ifconfig] <local> the local address for the tun/tap device" << std::endl
282 << " <remote|netmask> the remote address(tun) or netmask(tap)" << std::endl;
283 std::cout << " [-x|--post-up-script] <script> script gets called after interface is created" << std::endl;
284 std::cout << " [-w|--window-size] <window size> seqence number window size" << std::endl;
285 std::cout << " [-m|--mux] <mux-id> the multiplex id to use" << std::endl;
286 std::cout << " [-c|--cipher] <cipher type> payload encryption algorithm" << std::endl;
287 std::cout << " [-K|--key] <master key> master key to use for encryption" << std::endl;
288 std::cout << " [-A|--salt] <master salt> master salt to use for encryption" << std::endl;
289 // std::cout << " [-k|--kd-prf] <kd-prf type> key derivation pseudo random function" << std::endl;
290 std::cout << " [-a|--auth-algo] <algo type> message authentication algorithm" << std::endl;
293 void Options::printOptions()
295 Lock lock(mutex);
296 std::cout << "Options:" << std::endl;
297 std::cout << "daemonize=" << daemonize_ << std::endl;
298 std::cout << "chroot=" << chroot_ << std::endl;
299 std::cout << "username='" << username_ << "'" << std::endl;
300 std::cout << "chroot_dir='" << chroot_dir_ << "'" << std::endl;
301 std::cout << "pid_file='" << pid_file_ << "'" << std::endl;
302 std::cout << "sender_id='" << sender_id_ << "'" << std::endl;
303 std::cout << "local_addr='" << local_addr_ << "'" << std::endl;
304 std::cout << "local_port='" << local_port_ << "'" << std::endl;
305 std::cout << "local_sync_addr='" << local_sync_addr_ << "'" << std::endl;
306 std::cout << "local_sync_port='" << local_sync_port_ << "'" << std::endl;
307 std::cout << "remote_addr='" << remote_addr_ << "'" << std::endl;
308 std::cout << "remote_port='" << remote_port_ << "'" << std::endl;
309 std::cout << "dev_name='" << dev_name_ << "'" << std::endl;
310 std::cout << "dev_type='" << dev_type_ << "'" << std::endl;
311 std::cout << "ifconfig_param_local='" << ifconfig_param_local_ << "'" << std::endl;
312 std::cout << "ifconfig_param_remote_netmask='" << ifconfig_param_remote_netmask_ << "'" << std::endl;
313 std::cout << "post_up_script='" << post_up_script_ << "'" << std::endl;
314 std::cout << "seq_window_size='" << seq_window_size_ << "'" << std::endl;
315 std::cout << "mux_id='" << mux_ << "'" << std::endl;
316 std::cout << "cipher='" << cipher_ << "'" << std::endl;
317 std::cout << "key=" << key_.getHexDumpOneLine() << std::endl;
318 std::cout << "salt=" << salt_.getHexDumpOneLine() << std::endl;
319 std::cout << "kd_prf='" << kd_prf_ << "'" << std::endl;
320 std::cout << "auth_algo='" << auth_algo_ << "'" << std::endl;
322 std::cout << "connect_to=";
323 ConnectToList::const_iterator it = connect_to_.begin();
324 for(; it != connect_to_.end(); ++it)
325 std::cout << "'" << it->host << "','" << it->port << "';";
326 std::cout << std::endl;
329 std::string Options::getProgname()
331 Lock lock(mutex);
332 return progname_;
336 Options& Options::setProgname(std::string p)
338 Lock lock(mutex);
339 progname_ = p;
340 return *this;
343 bool Options::getDaemonize()
345 return daemonize_;
348 Options& Options::setDaemonize(bool d)
350 daemonize_ = d;
351 return *this;
354 bool Options::getChroot()
356 return chroot_;
359 Options& Options::setChroot(bool c)
361 chroot_ = c;
362 return *this;
365 std::string Options::getUsername()
367 Lock lock(mutex);
368 return username_;
371 Options& Options::setUsername(std::string u)
373 Lock lock(mutex);
374 username_ = u;
375 return *this;
378 std::string Options::getChrootDir()
380 Lock lock(mutex);
381 return chroot_dir_;
384 Options& Options::setChrootDir(std::string c)
386 Lock lock(mutex);
387 chroot_dir_ = c;
388 return *this;
391 std::string Options::getPidFile()
393 Lock lock(mutex);
394 return pid_file_;
397 Options& Options::setPidFile(std::string p)
399 Lock lock(mutex);
400 pid_file_ = p;
401 return *this;
404 ConnectToList Options::getConnectTo()
406 Lock lock(mutex);
407 return connect_to_;
410 sender_id_t Options::getSenderId()
412 return sender_id_;
415 Options& Options::setSenderId(sender_id_t s)
417 sender_id_ = s;
418 return *this;
421 std::string Options::getLocalAddr()
423 Lock lock(mutex);
424 return local_addr_;
427 Options& Options::setLocalAddr(std::string l)
429 Lock lock(mutex);
430 local_addr_ = l;
431 return *this;
434 std::string Options::getLocalSyncAddr()
436 Lock lock(mutex);
437 return local_sync_addr_;
440 Options& Options::setLocalSyncAddr(std::string l)
442 Lock lock(mutex);
443 local_sync_addr_ = l;
444 return *this;
447 std::string Options::getLocalPort()
449 return local_port_;
452 Options& Options::setLocalPort(std::string l)
454 local_port_ = l;
455 return *this;
458 std::string Options::getLocalSyncPort()
460 return local_sync_port_;
463 Options& Options::setLocalSyncPort(std::string l)
465 local_sync_port_ = l;
466 return *this;
469 std::string Options::getRemoteSyncPort()
471 return remote_sync_port_;
474 Options& Options::setRemoteSyncPort(std::string l)
476 remote_sync_port_ = l;
477 return *this;
480 std::string Options::getRemoteSyncAddr()
482 Lock lock(mutex);
483 return remote_sync_addr_;
486 Options& Options::setRemoteSyncAddr(std::string r)
488 Lock lock(mutex);
489 remote_sync_addr_ = r;
490 return *this;
493 std::string Options::getRemoteAddr()
495 Lock lock(mutex);
496 return remote_addr_;
499 Options& Options::setRemoteAddr(std::string r)
501 Lock lock(mutex);
502 remote_addr_ = r;
503 return *this;
506 std::string Options::getRemotePort()
508 return remote_port_;
511 Options& Options::setRemotePort(std::string r)
513 remote_port_ = r;
514 return *this;
517 Options& Options::setRemoteAddrPort(std::string addr, std::string port)
519 Lock lock(mutex);
520 remote_addr_ = addr;
521 remote_port_ = port;
522 return *this;
525 std::string Options::getDevName()
527 Lock lock(mutex);
528 return dev_name_;
531 std::string Options::getDevType()
533 Lock lock(mutex);
534 return dev_type_;
537 Options& Options::setDevName(std::string d)
539 Lock lock(mutex);
540 dev_name_ = d;
541 return *this;
544 Options& Options::setDevType(std::string d)
546 Lock lock(mutex);
547 dev_type_ = d;
548 return *this;
551 std::string Options::getIfconfigParamLocal()
553 Lock lock(mutex);
554 return ifconfig_param_local_;
557 Options& Options::setIfconfigParamLocal(std::string i)
559 Lock lock(mutex);
560 ifconfig_param_local_ = i;
561 return *this;
564 std::string Options::getIfconfigParamRemoteNetmask()
566 Lock lock(mutex);
567 return ifconfig_param_remote_netmask_;
570 Options& Options::setIfconfigParamRemoteNetmask(std::string i)
572 Lock lock(mutex);
573 ifconfig_param_remote_netmask_ = i;
574 return *this;
577 std::string Options::getPostUpScript()
579 Lock lock(mutex);
580 return post_up_script_;
583 Options& Options::setPostUpScript(std::string p)
585 Lock lock(mutex);
586 post_up_script_ = p;
587 return *this;
590 window_size_t Options::getSeqWindowSize()
592 return seq_window_size_;
595 Options& Options::setSeqWindowSize(window_size_t s)
597 seq_window_size_ = s;
598 return *this;
601 std::string Options::getCipher()
603 Lock lock(mutex);
604 return cipher_;
607 Options& Options::setCipher(std::string c)
609 Lock lock(mutex);
610 cipher_ = c;
611 return *this;
614 std::string Options::getKdPrf()
616 Lock lock(mutex);
617 return kd_prf_;
620 Options& Options::setKdPrf(std::string k)
622 Lock lock(mutex);
623 kd_prf_ = k;
624 return *this;
627 std::string Options::getAuthAlgo()
629 Lock lock(mutex);
630 return auth_algo_;
633 Options& Options::setAuthAlgo(std::string a)
635 Lock lock(mutex);
636 auth_algo_ = a;
637 return *this;
640 u_int16_t Options::getMux()
642 Lock lock(mutex);
643 return mux_;
646 Options& Options::setMux(u_int16_t m)
648 Lock lock(mutex);
649 mux_ = m;
650 return *this;
653 Buffer Options::getKey()
655 Lock lock(mutex);
656 return key_;
659 Options& Options::setKey(std::string k)
661 Lock lock(mutex);
662 key_ = k;
663 return *this;
666 Buffer Options::getSalt()
668 Lock lock(mutex);
669 return salt_;
672 Options& Options::setSalt(std::string s)
674 Lock lock(mutex);
675 salt_ = s;
676 return *this;